如何防止UIImage.FromImage内存泄漏(context.ToImage())?(How

2019-09-30 04:36发布

我有以下功能,以像素的字节数组转换为图像。 不过,我在该行内存泄漏:

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

当我注释掉线以上,泄漏消失。 泄漏是如此糟糕,iOS版约30秒启动的内杀死我的应用程序。 这是因为该行的代码。

如何防止这种内存泄漏? 有没有更好的方式做什么,我试图做的?

    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();
        }
    }

下面是分析截图(当代码的关键行注释掉检查的项目全部消失)。 你可以看到选中的项目(尤其是malloc的)如何随时间增长。

下面是malloc的1.50KB的放大视图。 你可以在它被调用CGBitmapContextCreateImage和CGDataProviderCreateWithCopyOfData,然后一个malloc右侧的扩展详细信息窗格中看到。

这里是Rolf的建议,剖析截图。 我跑了图像循环两次。 你可以看到它清理在第一循环结束额外的内存,但系统没有清理速度不够快,第二次和iOS杀死我的应用程序(你可以看到内存不足警告标志右上角角)。

Answer 1:

像这样做:

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


文章来源: How do I prevent a memory leak with UIImage.FromImage(context.ToImage())?