简体   繁体   English

Memory 在循环中创建位图时出现溢出异常

[英]Memory overflow exception when creating bitmaps in a loop

I have to import a large amount of image crops off of many images that are all ready stored in my database.我必须从已准备好存储在我的数据库中的许多图像中导入大量图像裁剪。 I have tried using statements and disposing of my bitmap objects each time.我尝试使用语句并每次处理我的 bitmap 对象。 But I am still getting a Memory Overflow Exception that my system is out of memory.但是我仍然收到 Memory 溢出异常,即我的系统超出了 memory。

Here is some sample code of what I am doing.这是我正在做的一些示例代码。

public void CropImage(List<ImageClass> data)
{
    foreach (var obj in data)
    {
        //I have a data base method that returns a data object that 
        //contains the file bytes of the image id in data: 'file'
        //My List<ImageClass> data contains an ID of the original image
        //start x,y coords for the upper left corner of the rectangle,
        //and the width and height of the rectangle.

        Image img = Image.FromStream(new MemoryStream(file.Data));
        Bitmap bmp = new Bitmap((Bitmap)img);
        Rectangle cropArea = new Rectangle(obj.x_coordinate,
                                           obj.y_coordinate,
                                           obj.width,
                                           obj.height);

        Bitmap cropImage = bmp.Clone(cropArea, bmp.PixelFormat);

        SaveFile(cropImage, file, obj.scanID);

        img.Dispose();
        bmp.Dispose();
        cropImage.Dispose();
    }
}


    public void SaveFile(Bitmap cropImage, FileData file, int OCRscanID)
    {
        EncoderParameters encoderParams = new EncoderParameters();
        encoderParams.Param[0] = new EncoderParameter(
                                          System.Drawing.Imaging.Encoder.Quality,
                                          50L);

        ImageCodecInfo codecInfo = GetEncoderInfo("image/jpeg");
        MemoryStream newImage = new MemoryStream();
        cropImage.Save(newImage, codecInfo, encoderParams);

        byte[] newData = newImage.ToArray();

        //Saving data bytes to database of the cropped image 
    }

    private ImageCodecInfo GetEncoderInfo(string mimeType)
    {
        int j;
        ImageCodecInfo[] encoders;
        encoders = ImageCodecInfo.GetImageEncoders();
        for (j = 0; j < encoders.Length; ++j)
        {
            if (encoders[j].MimeType == mimeType)
                return encoders[j];
        }
        return null;
    }

I know I can trim up some of the code like searching for an encoder to just use the image/jpeg.我知道我可以修剪一些代码,例如搜索编码器以仅使用图像/jpeg。 But i had another application for this code another project.但是我有另一个应用程序用于这个代码另一个项目。 I just can't seem to get past the memory overflow.我似乎无法通过 memory 溢出。

I need to cycle through about 20k images.我需要循环浏览大约 20k 图像。

You're not disposing your memory streams.你没有处理你的 memory 流。 Everything that implements IDisposable should be disposed.所有实现IDisposable的东西都应该被处理掉。

Is a memory leak created if a MemoryStream in .NET is not closed? 如果 .NET 中的 MemoryStream 未关闭,是否会创建 memory 泄漏?

Ants memory profiler is an invaluable tool for debugging these types of problems. Ants memory 分析器是调试此类问题的宝贵工具。 At first glance the only problem I see is that you have a leak if you ever throw an exception.乍一看,我看到的唯一问题是,如果你抛出异常,就会发生泄漏。

what I would do is to use using instead of manually disposing your objects and make sure you are logging exceptions.我要做的是使用using而不是手动处理您的对象,并确保您正在记录异常。 If that doesn't do it and the memory profiler doesn't show you any problems try adding a GC.collect() as this may help if your large object heap is getting fragmented, which is relatively likely with this sort of code.如果这样做不行,并且 memory 分析器没有向您显示任何问题,请尝试添加GC.collect()因为如果您的大型 object 堆变得碎片化,这可能会有所帮助,这种代码相对可能。

There are a certain number of options available to you which can be helpful like bitmap compress, bitmap recycle, bitmap scaling, catching bitmaps.您可以使用一定数量的选项,例如 bitmap 压缩、bitmap 回收、bitmap 缩放、捕获位图。

Catching Bitmaps捕捉位图

Catching OutOfMemoryError in decoding Bitmap 在解码 Bitmap 时捕获 OutOfMemoryError

Recycle bitmaps回收位图

Android: Bitmap recycle() how does it work? Android: Bitmap recycle() 它是如何工作的?

Bitmap compress Bitmap 压缩

How to make Bitmap compress without change the bitmap size? 如何在不改变 bitmap 大小的情况下使 Bitmap 压缩?

Bitmap scaling Bitmap缩放

Android - Scale and compress a bitmap Android - 缩放和压缩 bitmap

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM