2017-12-26 32 views
0

私はiOSアプリケーションに一見無害な変更を加えました。アプリケーションがクラッシュするまで、メモリ消費量は常に増加し続けるため、アプリケーションはクラッシュしています。これは、おそらくメモリ消費量が10倍になったことでしょう。どのクラスが最もメモリを消費しているかをどのようにして知ることができますか?

どのクラスまたは構造体がこれに責任を負うのかをどのようにして知ることができますか?

CVPixelBuffer:800メガバイト CMSampleBuffer:100メガバイト CIImage:50メガバイト

私はXcodeののメモリデバッガおよび楽器の両方に見えたが、何も見つからなかった私のようなものを探しています。

+0

アプリでメモリリークを検出しようとしましたか? –

+1

おそらく、ローカル変数としてメモリ消費型を導入したのでしょう。理論的にはスタック領域を使い果たす可能性のある構造体と非常に大きなC配列が候補になる可能性があります。おそらくヒープ上に何かを置いておくタイトなループです。問題の原因となっている変更を絞り込むための改訂履歴はありませんか? –

+0

@ Kamil.S私はどちらがコミットしているのか知っていますが、それはまだGitにコミットされていません。私は深い再帰を持っていないので、スタックスペースではありません。慎重に新しいコードをコメントアウトして行ごとにコメントを外すことで、問題はhttps://developer.apple.com/documentation/coreimage/cifilter/2138288-initにあることが判明しました。私がCIFilterを作成してそれを捨てると、それは起こるべきではないメモリをリークします。しかし、XcodeやInstrumentsでは、すべてのクラスを使用されたメモリ(そのクラスのすべてのインスタンスによって累積的に)で並べ替えるという、より良い方法を提供していますか? –

答えて

0

CIFilter initialiserのメモリリークです。再現する手順は次のとおりです。

  1. 生のサンプルバッファをキャプチャするには、AVFoundationを使用します。 CVPixelBuffer取得する
  2. コールCMSampleBufferGetImageBuffer():CIFilterが捨てられていることを
  3. お知らせ:
  4. はCIFilterを作成します。
  5. 上記の手順がすべて完了したら、手順1に戻り、100回繰り返します。

    let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)! 
    let metadata = CMCopyDictionaryOfAttachments(nil, sampleBuffer, kCMAttachmentMode_ShouldPropagate)! 
    _ = CIFilter(cvPixelBuffer: pixelBuffer, properties: metadata) 
    

    期待される結果::

    スウィフトオブジェクトを作成し、メモリリークが発生しませんそれを捨てる

は、ここでは、コードです。

実績:

  • のiOSアプリを殺すまで、メモリ使用量は、ギガバイト以上に無限の方法で成長します。
  • CIFilterを作成する行をコメントアウトすると、この問題は解決されます。
  • dngPhotoDataRepresentation()を使用してRAWサンプルバッファをNSDataに変換し、それをCIFilter初期化子に渡すとこの問題は解決されますが、遅くなります。
  • CVPixelBufferはリリースされていないようですが、CIFilter(またはiOS内部の他のコードが漏れているため)です。 CVPixelBufferへの弱い参照を作成することで検証しました。バッファーが解放された場合、弱参照はゼロになりますが、弱参照はゼロになりません。
  • (代わりにRAWの)BGRAサンプル緩衝液を捕捉しCIImageに変換すると、メモリリークが発生しない。

    _ = CIImage(cvImageBuffer:pixelBuffer、オプション:[kCIImageProperties:メタデータ])

iPhone 7 PlusおよびiPhone XのiOS 11にあります。