1

ピクセルのバイト配列を画像に変換する次の関数があります。ただし、次の行にメモリ リークがあります。

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

上記の行をコメントアウトすると、リークがなくなります。リークがひどすぎて、起動から約 30 秒以内に iOS がアプリを強制終了してしまいます。これは、このコード行が原因です。

このメモリリークを防ぐにはどうすればよいですか? 私がやろうとしていることを行うためのより良い方法はありますか?

    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 を呼び出していることがわかります。 Malloc 1.50KB プロファイリングのスクリーンショット

これは、Rolf の提案によるプロファイリングのスクリーンショットです。画像ループを 2 回実行しました。最初のループの最後に余分なメモリがクリーンアップされていることがわかりますが、2 回目はシステムが十分な速さでメモリをクリーンアップせず、iOS がアプリを強制終了しました (右上にメモリ不足の警告フラグが表示されます)。コーナー)。 ここに画像の説明を入力

4

1 に答える 1

4

次のようにします。

using (var pool = new NSAutoreleasePool ()) {
    using (var img = context.ToImage ()) {
        unpackedImage = UIImage.FromImage (img); 
    }
}
于 2012-05-22T10:21:16.367 に答える