4

私たちは、24 時間年中無休で実行し続けることができるように十分に安定している必要がある iPad アプリでのメモリ リークと戦っています。そのため、メモリ リークは耐えられません。

簡単なテストとして、「Single View」テンプレートを使用して新しい iPad MonoTouch プロジェクトを作成し、iPad 自体 (iPad 第 3 世代、実行中またはメモリ内の他のアプリなし) で Instruments を使用して実行しました。

Instruments では、「Mark Memory」ボタンを頻繁に押し続けると、メモリを消費し続けます。多くはありませんが、時々少しずつ:

ここに画像の説明を入力

アプリは文字通り何もしていませんが、メモリを割り当てる何かが実行されていることは明らかです。

これは iOS の問題ですか、MonoTouch の問題ですか、それとも他の問題ですか?

24 時間年中無休の iPad アプリを作成する計画は現実的ですか? コードを追加し始めると、メモリ リークの量もエスカレートするのではないかと懸念しています。上の画像のリークでアプリがかなりの時間実行されることは明らかですが、それが増加すると、メモリがいっぱいになる期限がはるかに早くなります.

4

1 に答える 1

6

スクリーンショットはメモリ リークではなく、割り当てを示しています。Instruments にリークを追跡するように依頼できます。つまり、割り当てられたメモリへの参照が見つからない場所です。

しかし、もっとデータがなければ、それらが正常かどうかを判断することはできません. 少なくとも、割り当てがどこから来ているのかを知る必要がありますか? 楽器は、各割り当てに関する詳細を教えてくれます。各ヒープショットの下のツリーをドリルダウンして、割り当てがどこから来ているかを確認してください。

同様の状況は、キャッシングが原因であることが多く、これはすべてのレベルで行われています。アプリケーション コードの外では、iOS とそのフレームワークがキャッシングを行っていることがわかります (画像、Webkit など)。

Mono 自体はキャッシュを行い、必要に応じて拡張されるメモリ プールも使用します。割り当て (解放された場合でも) が表示されますが、これはリークではありません。解放されると、可能であれば (サイズなど) メモリが再利用されます。

もちろん、バグの可能性もあります (アプリ、フレームワーク、モノタッチ、iOS)。1 回の小さなリークでも、間違った場所 (たとえば、実行ループの一部、通知の処理など) で発生すると、アプリをクラッシュさせるのに十分です。割り当てがどこから来て、それらが(同じソースからの)繰り返し割り当てであるかを見つけることだけが、それらがどれほど重要かを教えてくれます。

編集(もっと)

そこで、昨夜、自分のアプリケーションで実験を行いました。以下のスクリーンショットは、13 時間 45 分にわたるヒープの増加を示しています。

13 時間 45 分を超えるヒープの増加

最初の 4 時間 (1 ~ 13) の間、アプリケーションはフォアグラウンドにありました。最後の部分 (14) では、アプリケーションはバックグラウンドにありました (夜は画面がオフ)。時間の経過とともに番号が下がる機会がないように、録音も#14以降で停止されました。

私のアプリケーションはより大きく (初期ベースラインは 5MB)、起動後は使用しませんでした。最初の「マーク ヒープ」は、初期化が完了したことを確認した時点で完了しました (かなり大きな80 MB のデータベースをロードしています)。OTOH は、マネージ コードにコールバックするを使用して、ネットワーク イベントもリッスンしNSNetServiceBrowserます (視覚的な手がかりはありません)。

Heapshot #1 を展開すると、スタックトレースが_ZL13_cache_mallocm, cache_fill,lookupMethodで終わる 48 バイトの単一のオブジェクト_class_lookupMethodAndLoadCache3が表示されます。呼び出し元の上位に表示されるアプリやモノはありません。

Heapshot #2 を展開すると、4 つのオブジェクトが表示されます。最初の 2 つは、スタック トレースにCA::Render::Encoder::ObjectCacche::invalidate(...)とがあります。CGNotificationCenterPostNotification3 番目は_cache_addForwardEntry、4 番目は Heapshot #1 のように見えますが、 3 番目と同様に_XReceivedStatusBarDataAndAction(私のアプリやモノタッチで直接行われたものではありません) から来ています。

Heapshot #3 を展開すると、10 個のオブジェクトが表示されます... リストするには少し長くなりますが、それらはすべて同じ_XReceivedStatusBarDataAndAction呼び出しの下にあります。

ヒープショット #4 を展開するときと同じパターン。

ヒープショット #5 には、割り当てがディスパッチ キュー (_xpc_connection_init) からのものであるが、マネージ (アプリ) または mono[touch] スタック フレームが表示されない (11 のうち) 1 つの違いがあります。

ヒープショット #6、#7、#8 を展開するときの同じパターン (#3 と同じ)。

ヒープショット #9 は空です (割り当てなし)。

ヒープショット #10、#11 は #3 と同様です。

ヒープショット #12 も空です。

ヒープショット #13 はほとんど #3 に似ていますが、同じ画像もキャッシュし、通知を受信したときにCA::Render::Image::caches_encoding()別の_cache_fill+がlookUpMethod発生しました_significantTimeChange(管理されていないか、以下の MT スタック フレームUIApplicationMain)。他のいくつかの割り当ては、通知に関連しています。

Heapshot #14 は主に通知に関するものです (バックグラウンドに移動するように指示されている可能性があります)。再びいくつかの_cache_fill割り当てがあります。

これは iOS の問題ですか、MonoTouch の問題ですか、それとも他の問題ですか?

MonoTouch や私のアプリを指しているものは何もありません。OTOH これを ObjC アプリと比較したことはありません (比較する時間がないかもしれません) が、使用されている API/サービスに応じて (そして同じことを行うアプリは同じように表示されるはずです)、非常に近いものを見ることができると思います配分)。

YMMV の前に述べたように、リーク (または意図しないメモリ保持) は多くの場合 API 固有です。インストゥルメント セッションで奇妙なスタック トレースが見つかった場合は、それらについてのバグ レポートを (スタック トレースに応じて Xamarin または Apple に) 記入してください。これにより、それらを分析して修正することができます (バグがある場合)。

24 時間年中無休の iPad アプリを作成する計画は現実的ですか?

アプリを 24 時間年中無休で実行することは可能だと思いますが、ユーザーの協力が必要です (これは非現実的かもしれません)。別のアプリケーション (ホーム ボタン、ジェスチャ) に切り替えると、アプリはフォアグラウンドになくなり、Apple はバックグラウンド アプリを強制終了してメモリを再利用できることを意味します。たとえば、App X がメモリ不足になり、iOS がフォアグラウンド アプリを満足させるためにバックグラウンド アプリを要求し、その後強制終了します。

于 2013-01-06T01:20:57.683 に答える