3

メモリストンピングが発生していると思われる iOS アプリを持っています。そこで、Xcode で Guard Malloc、Guard Edges、および Scribble を有効にして実行し、追跡を試みました。しかし、Guard Malloc を有効にすると、非常に奇妙な方法で事態が悪化し始めます。一部の (予測可能な) 状況では、ビューの背景が描画されず、背後のビューが透けて見えることがあります。ファイルのダウンロードを行うと、ダウンロードの最後にメイン スレッドでアプリがクラッシュし、スタックにコードが何もなく ( 以外main)、コンソールに次のようなグラフィック エラーが記録されることがあります。

<Error>: CGBitmapContextInfoCreate: unable to allocate 201000 bytes for bitmap data
<Error>: CGContextSetInterpolationQuality: invalid context 0x0

これらの一部 ( などCGBitmapContextInfoCreate) は、コードのどこにも使用されていません。

最後に記録されたものは次のようなものです。

Failed to VM allocate 262144 bytes
Explicitly trapping into debugger!!!

他の誰かが Guard Malloc にこれらの種類のエラーを引き起こしたことがありますか? これの根源は何でしょうか?

4

1 に答える 1

4

Guard Malloc は、メモリ管理ユニット (MMU) を介して機能します。MMU を使用すると、メモリの特定の部分にプロセスによるアクセスを許可し、特定の領域を違法としてフラグを付けることができます。これが、保護されたメモリの本質です。これは、メモリを個々のページ (多くの場合 4 KB) に分割し、関連するアクセス許可を各ページに割り当てることによって行われます。膨大な量のストレージが必要になるため、アドレスごとに属性を個別に保存することはできません。

不正アクセス例外を発生させるのは MMU です。

通常のコードを実行すると、多くのデータが 4kb よりも小さいため、ほとんどのデータが他のデータとページを共有するため、一部の境界外アクセスで例外が発生しないことを意味します。また、書き込み対象の配列ではない場合や、ページが新しいオブジェクトによって再利用されている場合でも、ページ内の任意の場所への書き込みが許容されます。

したがって、Guard Malloc は各オブジェクトに個別のページを提供します。これにより、すべてのオブジェクト サイズがページ サイズに切り上げられるため、メモリ フットプリントが大幅に増加します。これはまた、パフォーマンスを低下させるものでもあります — キャッシュのための賢明なアルゴリズムは、正しく機能しなくなります。

副作用として、移動するストレージがはるかに少なくなります。NSString通常 280 バイトのストレージを占有する があるとします。さて、それはページ全体を占めています。そのため、メモリが不足するのがずっと早くなります。(編集:および以下のグレッグのコメントによると、ページが割り当てられると、Guard Mallocはそれがプールに戻ることを許可しないため、メモリフットプリントが累積されます。つまり、与えられたにもかかわらず、ほぼ確実に最終的にメモリが不足します[ほとんど] すべてのオブジェクトがヒープに移動し、オブジェクトを返すことは正常です)

ガード エッジは、すべての割り当ての間に空のページを挿入することで、その状況を悪化させる可能性があります。そのため、割り当てられたすべてのオブジェクトは、仮想メモリ プールから少なくとも 1 つの余分なページを取得します。仮想プールのサイズが物理プールに十分近い場合、影響を受ける可能性があります。

CGBitmapContextInfoCreateUIView内容を更新するように求められたときに、使用している標準の s のいずれかによってほぼ確実に内部的に使用されます。システムには要求を満たすのに十分なメモリがありません。ビューがその結果を適切に処理しようとしていないようです。

おそらく唯一の有意義なアドバイスは、デバッグ ツールを個別に、単独で試すことです。

于 2013-06-06T23:06:04.673 に答える