3

次のコードは、約 200 回の呼び出し後にクラッシュします。各呼び出しの後に GC を試し、別の GC で MemoryWarning ブロックを試みましたが、それでもクラッシュします。

public byte[] ConvertImage(string base64String)
{
    try
    {
        byte[] encodedDataAsBytes = Convert.FromBase64String ( base64String );
        base64String = "";
        NSData data = UIImage.LoadFromData ( NSData.FromArray ( encodedDataAsBytes ) ).AsPNG();
        encodedDataAsBytes = null;
        Byte[] returnBytes2 = new Byte[data.Length];
        System.Runtime.InteropServices.Marshal.Copy
        (data.Bytes, returnBytes2, 0, System.Convert.ToInt32(data.Length));
        data.Dispose();
        return returnBytes2;
    }
    catch(Exception ex)
    {
        Log.LogError("ConvertImage", ex);
        return null;
    }
}

ティア、リック

Xamarin サポートからの多くのヘッド バンギングと優れたヘルプの後、答えはメソッドをラップすることですusing (var pool = new NSAutoreleasePool ())

すべてが順調です!ああ、もう 1 つのポイントとして、.PNG を .JPEG に変更すると、負荷も軽減されました。

4

1 に答える 1

3

これはかなりメモリ集約的です。base64 stringbyte[]配列、 、NSDataUIImage2 番目NSDataの 、 2 番目のbyte[]配列。これは、作業中の画像に必要なメモリの何倍にもなります。

コードの呼び出し方法 (画像の束に対するループなど) によっては、GC がメモリを再利用できるよりも速くメモリを割り当てている可能性があります。ある時点で、iOS はメモリ警告をトリガーし (ただし、これはループでは役に立ちません)、メモリ使用量が急速に減らなければ、あなたを殺してしまいます。

IDisposableコードが作成するすべてのインスタンスを破棄することで、メモリ要件を簡単に下げることができます。現在、NSData作成した 2 つのインスタンスのうちの 1 つだけを破棄しており、UIImage. 次のようにすべてを破棄できます。

byte[] encodedDataAsBytes = Convert.FromBase64String ( base64String );
using (var nsd1 = NSData.FromArray ( encodedDataAsBytes ))
using (var img = UIImage.LoadFromData ( nsd1 ))
using (NSData data = img.AsPNG ()) {
    byte[] returnBytes2 = new byte [data.Length];
    Marshal.Copy (data.Bytes, returnBytes2, 0, (int) data.Length);
    return returnBytes2;
}

次に、後でコードの目的は何ですか? byte[]つまり、PNG 画像を含むで何をしていますか? それ自体はあまり役に立ちませんが、ディスクに保存するだけなら、最後の割り当てNSDataをスキップしてディスクに保存することができます。byte[]

使用法に依存する他のトリックも適用できます (たとえばbyte[]、可能な場合は 2 番目のバッファーを再利用する) が、コードがどのように使用されているかについて詳しく知る必要があります。

于 2012-10-20T01:14:17.510 に答える