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

时间:2012-05-22 05:53:02

标签: c# xamarin.ios uiimage byte pixels

我有以下函数将字节数组像素转换为图像。但是,我在行中有内存泄漏:

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)如何随着时间的推移而增长。

Profiling Screenshot

这是Malloc 1.50KB的放大视图。您可以在右侧的“扩展详细信息”窗格中看到它正在调用CGBitmapContextCreateImage和CGDataProviderCreateWithCopyOfData,然后是malloc。 Malloc 1.50KB Profiling Screenshot

以下是Rolf建议的剖析截图。我跑了两次图像循环。您可以看到它在第一个循环结束时清理了额外的内存,但系统没有第二次快速清理它并且iOS杀死了我的应用程序(您可以在右上角看到低内存警告标记角)。 enter image description here

1 个答案:

答案 0 :(得分:4)

这样做:

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