How do I prevent a memory leak with UIImage.FromImage(context.ToImage())?

社会主义新天地 提交于 2019-12-24 10:40:40

问题


I have the following function to convert a byte array of pixels into an image. However, I have a memory leak in the line:

unpackedImage = UIImage.FromImage(context.ToImage());

When I comment out the line above, the leak goes away. The leak is so bad that iOS is killing my app within about 30 seconds of startup. It's because of this line of code.

How do I prevent this memory leak? Is there a better way to do what I am trying to do?

    public static void DrawCustomImage2(IntPtr buffer, int width, int height, int bytesPerRow, CGColorSpace colSpace, byte[] rawPixels, ref UIImage unpackedImage)
    {
        GCHandle pinnedArray = GCHandle.Alloc(rawPixels, GCHandleType.Pinned);
        IntPtr pointer = pinnedArray.AddrOfPinnedObject();

        // Set a grayscale drawing context using the image buffer
        CGBitmapContext context = new CGBitmapContext(pointer, width, height, 8, bytesPerRow, colSpace, CGImageAlphaInfo.None);

        // Turning off interpolation and Antialiasing is supposed to speed things up
        context.InterpolationQuality = CGInterpolationQuality.None;
        context.SetAllowsAntialiasing(false);

        try
        {
            unpackedImage = UIImage.FromImage(context.ToImage());   // Convert the drawing context to an image and set it as the unpacked image
        } finally
        {
            pinnedArray.Free();
            if (context != null)
                context.Dispose();
        }
    }

Here is the profiling screenshot (checked items all disappear when the critical line of code is commented out). You can see how the checked items (especially the Malloc) grow over time.

Here is the zoom-in view on the Malloc 1.50KB. You can see in the Extended Detail pane on the right that it is calling CGBitmapContextCreateImage and CGDataProviderCreateWithCopyOfData and then a malloc.

Here is the profiling screenshot with Rolf's suggestion. I ran the image loop twice. You can see that it cleans up the extra memory at the end of the first loop, but the system didn't clean it up fast enough the second time and iOS killed my app (you can see the low memory warning flags in the top right corner).


回答1:


Do it like this:

using (var pool = new NSAutoreleasePool ()) {
    using (var img = context.ToImage ()) {
        unpackedImage = UIImage.FromImage (img); 
    }
}


来源:https://stackoverflow.com/questions/10696412/how-do-i-prevent-a-memory-leak-with-uiimage-fromimagecontext-toimage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!