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

C# 如何使用UIImage.FromImage(context.ToImage())防止内存泄漏?,c#,xamarin.ios,uiimage,byte,pixels,C#,Xamarin.ios,Uiimage,Byte,Pixels,我有以下函数将像素字节数组转换为图像。但是,我有一个内存泄漏: UnpaceImage=UIImage.FromImagecontext.ToImage 当我注释掉上面的行时,泄漏消失了。漏洞非常严重,iOS在启动后30秒内就将我的应用程序杀死。这是因为这行代码 如何防止内存泄漏?有没有更好的方法来做我想做的事情 public static void DrawCustomImage2(IntPtr buffer, int width, int height, int bytesPerRo

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

UnpaceImage=UIImage.FromImagecontext.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。

下面是罗尔夫建议的分析截图。我运行了两次图像循环。您可以看到,它在第一个循环结束时清理了多余的内存,但第二次系统清理速度不够快,iOS杀死了我的应用程序。您可以在右上角看到内存不足警告标志。

这样做:

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

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

你的建议有点奏效……你可以从上面的屏幕截图中看到,它在我循环结束时清理了内存,但这还不够好,第二个循环就被iOS扼杀了。我怎样才能让它清理循环中各个点的内存呢?我在finally块中放置了一个手动GC.Collect,现在一切似乎都很好!非常感谢你的迅速帮助!!有没有比直接调用GC.Collect更好的方法来解决这个问题呢?你的建议有点奏效了……你可以从上面的截图中看到,它在我循环结束时清理了内存,但这还不足以进行第二个循环,iOS杀死了应用程序。我怎样才能让它清理循环中各个点的内存呢?我在finally块中放置了一个手动GC.Collect,现在一切似乎都很好!非常感谢你的迅速帮助!!有没有比显式调用GC.Collect更好的攻击方法?