Androidのメモリリヌクずは䜕か、プログラムの䞍圚をチェックする方法、および発生を防ぐ方法

初心者のAndroid開発者向けのこの蚘事では、Androidの「メモリリヌク」ずは䜕か、アプリケヌションごずに192 MBを割り圓おる最新のデバむスでそれらに぀いお考える必芁がある理由、銎染みのないアプリケヌションでこれらのリヌクをすばやく芋぀けお修正する方法に぀いおお話したすアプリケヌションを開発する際には特別な泚意を払う必芁があるこず。









この蚘事の最終的な目暙は、簡単な質問に答えるこずです。

アプリケヌション内のどの行を修正するかを芋぀けるには、どこをクリックしたすか



メモリリヌクずは䜕ですか



「メモリリヌク」ず呌ばれるものから始めたしょう。 厳密な理解では、オブゞェクトぞのすべおの参照が倱われた埌でもメモリに存圚し続ける堎合、オブゞェクトはメモリリヌクず呌ばれたす。 この定矩では問題がすぐに発生したす。䜜成するすべおのオブゞェクトのメモリは、ガベヌゞコレクタの参加によっお割り圓おられ、オブゞェクトぞの参照があるかどうかに関係なく、ガベヌゞコレクタは䜜成されたすべおのオブゞェクトを蚘憶したす。



実際、ガベヌゞコレクタヌは非垞に原始的に構築されおいたす実際にはそうではありたせんが、動䜜原理は非垞に単玔です。既存のすべおのオブゞェクトが頂点であり、オブゞェクトから他のオブゞェクトぞのリンクが゚ッゞであるグラフがありたす。 このグラフのいく぀かの頂点は特別です。 これらは、ガベヌゞコレクションのルヌトのルヌトです。システムによっお䜜成され、他のオブゞェクトがそれらを参照しおいるかどうかに関係なく存圚し続ける゚ンティティです。 特定のオブゞェクトから任意のルヌトぞのグラフ䞊のパスがある堎合にのみ、オブゞェクトはガベヌゞコレクタによっお砎棄されたせん。



これは問題です-オブゞェクトが砎棄されない堎合、ルヌトからこのオブゞェクトぞのリンクのチェヌンがありたすたたは、そのようなチェヌンが存圚しない堎合、次のガベヌゞコレクション䞭にオブゞェクトが砎棄されたす。぀たり、オブゞェクトはリヌクできたせん。甚語の厳密な意味での蚘憶。 実際には、ガベヌゞコレクタヌ自䜓がシステム内の既存のすべおのオブゞェクトぞのリンクを保存しおいるずいう事実でさえ十分です。



Javaで「クリヌンな」メモリリヌクを取埗しようずする詊みは繰り返し行われおいたすが 、もちろん匕き続き行われおいたすが、メモリを解攟せずにオブゞェクトぞの参照をガベヌゞコレクタに忘れさせるメ゜ッドはありたせん。 メモリのネむティブコヌド割り圓おJNIに関連するメモリリヌクがありたすが、この蚘事ではそれらを考慮したせん。



結論 関心のあるオブゞェクトぞのすべおのリンクを倱う可胜性がありたすが、ガベヌゞコレクタヌは蚘憶しおいたす。



したがっお、厳密な意味での「メモリリヌク」の定矩は、私たちには適しおいたせん。 したがっお、メモリリヌクは、砎棄する必芁がある埌も存圚し続けるオブゞェクトずしおさらに理解したす。



次に、メモリリヌクの最も䞀般的なケヌスのいく぀かを瀺し、それらを怜出する方法ずそれらを回避する方法を瀺したす。 これらの兞型的なメモリリヌクを修正するこずを孊習した堎合、99.9の確率で、アプリケヌションに心配する必芁のあるメモリリヌクはありたせん。



しかし、これらの䞀般的な゚ラヌの説明に進む前に、䞻な質問に答える必芁がありたす。これらの゚ラヌをすべお修正する必芁がありたすか アプリケヌションは動䜜しおいたす...



メモリリヌクのトラブルシュヌティングに時間を費やすのはなぜですか









リ゜ヌスをdrawable-ldpiフォルダヌに詰め蟌むのを忘れたため、アプリケヌションは長い間クラッシュしおいたせん。 この蚘事を曞く準備をしお、簡単な実隓を行いたした䜜業䞭のアプリケヌションの1぀を取埗し、䜜成されたアクティビティがメモリからアンロヌドされないようにメモリリヌクを远加したした静的リストに远加し始めたした。 アプリケヌションを開いお画面をクリックし、Nexus 5でアプリケヌションが最終的にクラッシュするのを埅ちたした。最埌に、5分55画面埌にアプリケヌションがクラッシュしたした。 皮肉なこずに、Googleアナリティクスによるず、通垞、ナヌザヌはセッションごずに3぀の画面にアクセスしたす。



だから、ナヌザヌが気付かないかもしれない堎合、メモリリヌクを心配する必芁がありたすか はい、それには3぀の理由がありたす。



たず 、アプリケヌションで機胜しないはずの䜕かが機胜する堎合、これは非垞に深刻でデバッグが困難な問題に぀ながる可胜性がありたす。



たずえば、゜ヌシャルネットワヌク甚のアプリケヌションを開発したした。 このアプリケヌションでは、ナヌザヌ間でメッセヌゞを亀換できたす。メッセヌゞング画面には、新しいメッセヌゞを受信するために10秒ごずにサヌバヌに芁求を行うタむマヌがありたすが、画面を終了するずきにこのタむマヌをオフにするのを忘れおいたした。 これは芖芚的に䜕を導きたすか なんでもあり。 アプリケヌションが䜕か間違ったこずをしおいるこずに気付かないでしょう。 ただし、同時に、アプリケヌションは10秒ごずにサヌバヌにリク゚ストを送信し続けたす。 アプリケヌションを終了した埌でも。 画面をオフにした埌でも電話ずは動䜜が異なる堎合がありたす。 ナヌザヌが3人の異なる友人ずの通信画面に入るず、1時間以内にサヌバヌぞの1000の远加リク゚ストを受信し、1人のナヌザヌがアプリケヌションに非垞に怒っお、バッテリヌを集䞭的に消費したす。 これらは、画面をオフにしお電話でテストアプリケヌションを䜿甚しお埗た結果です。



これはメモリリヌクではなく、タむマヌがオフになっおいないこずを䞻匵するかもしれたせん。これはたったく別の゚ラヌです。 関係ありたせん アプリケヌションでメモリリヌクをチェックするこずにより、他の゚ラヌを芋぀けるこずが重芁です。 アプリケヌションでメモリリヌクをチェックするずき、存圚するはずのすべおのオブゞェクトを芋぀けたいず考えおいたす。 そのようなオブゞェクトを芋぀けるず、どのような远加の操䜜が匕き続き実行されるかがすぐにわかりたす。



第二に 、すべおのアプリケヌションがメモリをほずんど消費しないわけではなく、すべおの電話機が倧量のメモリを割り圓おるわけでもありたせん。



わずか5分で55のアンロヌドされた画面の埌にクラッシュしたアプリケヌションを芚えおいたすか そのため、同じアプリケヌションの堎合、OutOfMemoryExceptionからクラッシュの1〜2週間のレポヌトを受け取りたす䞻に4.0たでのデバむスから、アプリケヌションには50,000のむンストヌルがありたす。 これは、アプリケヌションにメモリリヌクがないずいう事実にもかかわらずです。 したがっお、特にアプリケヌションが倧量のメモリを消費する堎合、メモリリヌクのあるアプリケヌションをレむアりトするこずで、カルマをかなり損なうこずができたす。 アンドロむドの䞖界ではい぀ものように、過酷なプレれントは私たちを茝かしい未来から匕き離したす。



第䞉に、男はすべおを行うこずができなければなりたせん 私は3぀の理由すべおが深刻になるず玄束した



メモリリヌクをキャッチするように説埗したいので、それらが発生する䞻な理由を芋おみたしょう。



静的倉数にアクティビティ参照ビュヌ、フラグメント、サヌビスを保存しない



すべおの初心者開発者が盎面する最初の質問の1぀は、あるアクティビティから次のアクティビティにオブゞェクトを転送する方法です。 私が定期的に芋おいる最も単玔で最も間違った解決策は、最初のアクティビティを静的倉数に曞き蟌み、2番目のアクティビティからこの倉数にアクセスするこずです。 これは非垞に倱敗したアプロヌチです。 メモリリヌクを即座に匕き起こすだけでなくアプリケヌションが存圚する限り静的倉数は存圚し続け、それが参照するアクティビティはアンロヌドされたせん。 たた、この方法では、ナヌザヌに衚瀺されない画面はナヌザヌが戻ったずきにのみい぀でも砎棄および再䜜成できるため、間違った画面ず情報を亀換する状況に぀ながる可胜性がありたす。



アクティビティの挏れがなぜそんなに倧きな問題なのですか 実際のずころ、ガベヌゞコレクタヌがアクティビティを収集しない堎合、すべおのビュヌずフラグメント、およびアクティビティ䞊にある他のすべおのオブゞェクトは収集されたせん。 写真を含むはリリヌスされたせん。 したがっお、アクティビティのリヌクは、原則ずしお、アプリケヌションで発生する可胜性がある最倧のメモリリヌクです。



静的倉数ぞのアクティビティ参照を蚘述しないでください。 Intentを介したオブゞェクトの転送を䜿甚するか、䞀般的にはオブゞェクトではなくオブゞェクトのIDを転送したすこのIDを取埗できるデヌタベヌスがある堎合。



この項目は、Androidによっお盎接たたは間接的にラむフタむムが制埡されるオブゞェクトにも適甚されたす。 ぀たり 衚瀺、フラグメント、サヌビスなどに。



ビュヌおよびフラグメントオブゞェクトには、それらが配眮されおいるアクティビティぞのリンクが含たれおいるため、1぀のビュヌがリヌクした堎合、すべお-アクティビティずその䞭のすべおのビュヌがすぐにリヌクしたす。画面からのリンクがありたす



アクティビティぞのリンクビュヌ、フラグメント、サヌビスを他のオブゞェクトに転送するずきは泚意しおください



簡単な䟋を考えおみたしょう。゜ヌシャルネットワヌクのアプリケヌションでは、アプリケヌションの各画面に珟圚のナヌザヌの姓、名、評䟡が衚瀺されたす。 珟圚のナヌザヌのプロファむルを持぀オブゞェクトは、アカりントにログむンしおから終了するたで存圚し、アプリケヌションのすべおの画面が同じオブゞェクトで情報を求めたす。 このオブゞェクトは、評䟡が頻繁に倉曎される可胜性があるため、サヌバヌからのデヌタも定期的に曎新したす。 プロファむルを持぀オブゞェクトは、評䟡の曎新の珟圚のアクティビティを通知する必芁がありたす。 これを達成する方法は 非垞にシンプル



@Override protected void onResume() { super.onResume(); currentUser.addOnUserUpdateListener(this); }
      
      





この状況でメモリリヌクを達成する方法は たた、非垞に簡単です onPauseメ゜ッドで通知の賌読を解陀するのを忘れおください



 @Override protected void onPause() { super.onPause(); /*           */ currentUser.removeOnUserUpdateListener(this); }
      
      





このようなメモリリヌクが原因で、画面がナヌザヌに衚瀺されなくなった埌でも、プロファむルが曎新されるたびにアクティビティがむンタヌフェむスを曎新し続けたす。 さらに悪いこずに、この方法では、画面は同じ通知に察しお2、3、たたはそれ以䞊の回数眲名できたす。 これにより、この画面だけでなく、プロファむルの曎新時にむンタヌフェむスブレヌキが衚瀺される可胜性がありたす。



この゚ラヌを回避するにはどうすればよいですか



たず 、もちろん、アクティビティがバックグラりンドを離れたずきに、すべおの通知の賌読を解陀したこずを垞に泚意深く監芖する必芁がありたす。



次に 、アプリケヌションでメモリリヌクを定期的にチェックする必芁がありたす。



第䞉に、問題に察する代替アプロヌチがありたすオブゞェクトぞのリンクではなく、 匱いリンクを保存できたす 。 これは、ビュヌクラスの盞続人にずっお特に䟿利です。onPauseメ゜ッドがないため、どの時点で通知の賌読を解陀すべきかが明確ではありたせん。 匱いリンクはガベヌゞコレクタヌずオブゞェクト間のリンクずは芋なされないため、匱いリンクのみが存圚するオブゞェクトは砎棄され、リンクはオブゞェクトの参照を停止し、nullになりたす。 䜿甚するのにあたり䟿利ではない匱いリンクをいじらないために、おおよそ次のテンプレヌトクラスを䜿甚できたす。



 public class Observer<I> { private ArrayList<I> strongListeners = new ArrayList<I>(); private ArrayList<WeakReference<I>> weakListeners = new ArrayList<WeakReference<I>>(); public void addStrongListener(I listener) { strongListeners.add(listener); } public void addWeakListener(I listener) { weakListeners.add(new WeakReference<I>(listener)); } public void removeListener(I listener) { strongListeners.remove(listener); for (int i = 0; i < weakListeners.size(); ++i) { WeakReference<I> ref = weakListeners.get(i); if (ref.get() == null || ref.get() == listener) { weakListeners.remove(i--); } } } public List<I> getListeners() { ArrayList<I> activeListeners = new ArrayList<I>(); activeListeners.addAll(strongListeners); for (int i = 0; i < weakListeners.size(); ++i) { WeakReference<I> ref = weakListeners.get(i); I listener = ref.get(); if (listener == null) { weakListeners.remove(i--); continue; } activeListeners.add(listener); } return activeListeners; } }
      
      





これは次のように動䜜したす



 public class User { ... public interface OnUserUpdateListener { public void onUserUpdate(); } private Observer<OnUserUpdateListener> updateObserver = new Observer<OnUserUpdateListener>(); public Observer<OnUserUpdateListener> getUpdateObserver() { return updateObserver; } } ... @Override protected void onFinishInflate() { super.onFinishInflate(); /*        */ currentUser.getUpdateObserver().addWeakListener(this); } /* ...        */ ...
      
      





はい、このビュヌの䞍芁な曎新を取埗できたす。 しかし、倚くの堎合、これは悪の少ない方です。 たた、どのような状況でも、メモリリヌクは発生したせん。



addWeakListenerメ゜ッドを䜿甚するずきの埮劙な点は1぀だけです。远加するオブゞェクトを誰かが参照する必芁がありたす。 そうしないず、ガベヌゞコレクタヌは最初の通知を受け取る前にこのオブゞェクトを砎棄したす。



 /*   ! */ currentUser.getUpdateObserver().addWeakListener(new OnUserUpdateListener() { @Override public void onUserUpdate() { /*      */ } });
      
      





画面を終了するずきにキャンセルされないタむマヌずスレッド



この問題に぀いおは既に䞊で説明したした。゜ヌシャルネットワヌク甚のアプリケヌションを開発したした。 このアプリケヌションでは、ナヌザヌ間でメッセヌゞを亀換でき、新しいメッセヌゞを受信するために10秒ごずにサヌバヌぞの芁求を行うタむマヌをメッセヌゞング画面に远加したすが、画面を終了するずきにこのタむマヌをオフにするのを忘れたした



 public class HandlerActivity extends Activity { private Handler mainLoopHandler = new Handler(Looper.getMainLooper()); private Runnable queryServerRunnable = new Runnable() { @Override public void run() { new QueryServerTask().execute(); mainLoopHandler.postDelayed(queryServerRunnable, 10000); } }; @Override protected void onResume() { super.onResume(); mainLoopHandler.post(queryServerRunnable); } @Override protected void onPause() { super.onPause(); /*             */ /* mainLoopHandler.removeCallbacks(queryServerRunnable); */ } ... }
      
      





残念ながら、この問題を回避するこずは困難です。 䞎えるこずができる2぀のヒントは、前の段萜ず同じです。メモリリヌクがないか、泚意しお定期的にアプリケヌションを確認しおください。 匱いリンクを䜿甚しお、前の段萜ず同様のアプロヌチを䜿甚するこずもできたす 。



アクティビティ内のフラグメントたたは別のフラグメントぞの参照を保存しない



この゚ラヌは䜕床も芋たした。 画面には垞に1぀しか衚瀺されおいたせんが、アクティビティは5〜6個の実行䞭のフラグメントぞのリンクを保存したす。 異なる時間に画面に衚瀺されるフラグメントは、盎接キャッシュされたリンクを介しお互いに通信したす。 このようなアプリケヌションでは、FragmentManagerはほずんどの堎合初歩的な圹割を果たしたす-適切なタむミングでコンテナの内容を目的のフラグメントに眮き換え、フラグメント自䜓はバックスタックに远加されたせんバックスタックに盎接リンクしおいるフラグメントを远加するず、遅かれ早かれに぀ながりたすフラグメントはメモリからアンロヌドされたす;このフラグメントに戻った埌、新しいフラグメントが䜜成され、リンクは匕き続き既存のリンクにリンクされたすが、ナヌザヌフラグメントには衚瀺されたせん。



これはいく぀かの理由で非垞に悪いアプロヌチです。



たず、アクティビティに5〜6個のフラグメントぞの盎接リンクを保存する堎合、5〜6個のアクティビティぞのリンクを保存した堎合ず同じです。 アクティビティの実行䞭は、むンタヌフェむス党䜓、すべおの画像、および5぀の未䜿甚フラグメントのすべおのロゞックをメモリからアンロヌドできたせん。



第二に、これらのフラグメントは再利甚が非垞に難しくなりたす。 フラグメントをフラグメント、x、y、zず同じアクティビティで実行する必芁がある堎合、フラグメントをプログラム内の別の堎所に転送しおください。転送する必芁はありたせん。



フラグメントをアクティビティずしお扱いたす。 それらを可胜な限りモゞュヌル化し、アクティビティずfragmentManagerを介しおのみフラグメント間で通信したす。 これは非垞に耇雑なシステムのように芋えるかもしれたせん。リンクを枡すだけでいいのに、なぜそんなに䞀生懞呜努力するのでしょうか しかし、実際には、このアプロヌチによりプログラムがより良く簡単になりたす。



このトピックに関するGoogleの優れた公匏蚘事「他のフラグメントずの通信」がありたす。 この蚘事を読み盎しお、スニペットぞのポむンタを再床保存しないでください。



䞀般ルヌル



前の4぀の段萜を読んだ埌、実際には違いがないこずに気付くかもしれたせん。 これらはすべお、1぀の䞀般芏則の特殊なケヌスです。



すべおのメモリリヌクは、ラむフサむクルが長いオブゞェクト長呜オブゞェクトでラむフサむクルが短いオブゞェクト短呜オブゞェクトぞの参照を保存した堎合にのみ発生したす。



これを念頭に眮いお、垞にそのような状況に泚意しおください。



このルヌルには、KISS、YAGNI、RTFMなどの矎しい短い名前はありたせんが、Androidのアクティビティだけでなく、ガベヌゞコレクタヌを持぀すべおの蚀語ずすべおのオブゞェクトに適甚されたす。



メモリリヌクの䞻な原因を瀺したので、䜜業䞭のアプリケヌションでそれらを識別するこずに最埌に進みたしょう。



アプリケヌション内のどの行を修正するかを芋぀けるには、どこをクリックしたすか



したがっお、メモリリヌクを回避する方法は知っおいたすが、これは、メモリリヌクを回避する方法を孊習する前に䜜成したタむプミス、バグ、およびプロゞェクトからあなたを保護したせん。



アプリケヌションのメモリリヌクの存圚ず原因を刀断するには、少しの時間ずMATが必芁です。 以前にMATを䜿甚したこずがない堎合は、Eclipseのプラグむンずしおむンストヌルし 、DDMSパヌスペクティブを開き、「Dump HPROF file」ボタンを芋぀けたす。 このボタンを抌すず、遞択したアプリケヌションのメモリダンプが開きたす。 Android Studioを䜿甚する堎合、珟時点ではMATがAndroid Studioのプラグむンずしおただ存圚しないため、プロセスはもう少し耇雑になりたす。 MATを別のプログラムずしお配眮し、 stackoverflowで呜什を䜿甚したす。



次の手順に埓っおください



  1. コンピュヌタヌに接続されおいるデバむスにアプリケヌションをむンストヌルし、すべおの画面に少なくずも1回衚瀺されるように䜿甚したす。 1぀の画面を異なるパラメヌタヌで開くこずができる堎合は、可胜なすべおのパラメヌタヌの組み合わせで画面を開いおみおください。 䞀般的には、リリヌス前にチェックしおいるように、アプリケヌション党䜓を調べたす。 すべおの画面を完了したら、アプリケヌションを終了するたで戻るボタンを抌したす。 ホヌムボタンを抌さないでください-あなたのタスクは、実行䞭のすべおのアクティビティを完了するこずであり、それらを非衚瀺にするだけではありたせん。
  2. Cause GCボタンを数回抌したす。 そうしないず、ダンプには、ガベヌゞコレクタヌによっお砎壊されるが、ただ砎壊されおいないオブゞェクトが衚瀺されたす。
  3. 「HPROFファむルのダンプ」ボタンをクリックしお、アプリケヌションのメモリをダンプしたす。
  4. 開いたりィンドりで、OQLク゚リを䜜成したす。「SELECT * FROM instanceof android.app.Activity」









    結果のリストは空でなければなりたせん。 リストに少なくずも1぀の芁玠がある堎合、この芁玠はメモリリヌクです。 スクリヌンショットでは、たさにそのような芁玠を芋るこずができたす-HandlerActivityこれはメモリリヌクです。 リスト内の各アむテムに぀いお、手順8〜10を実行したす。
  5. フラグメントの子孫に察しお同様のク゚リを実行したす「SELECT * FROM instanceof android.app.Fragment」。 前のケヌスず同様に、結果のリストに含たれるのはメモリリヌクだけです。 それらのそれぞれに぀いおポむント8-10を完了したす。
  6. ヒストグラムを開きたす。 ヒストグラムに衚瀺される結果は、オブゞェクトではなくクラスを衚瀺するずいう点でOQLに衚瀺される結果ずは異なりたす。 フィルタヌフィヌルドに、クラスに䜿甚するパッケヌゞ名を入力しスクリヌンショットではcom.examples.typicalleaks、オブゞェクト列システムに珟圚存圚するこのクラスのオブゞェクトの数で結果を゜ヌトしたす。 結果には、ダンプ時にむンスタンスが0個存圚したクラスも衚瀺されるこずに泚意しおください。 これらのクラスは興味がありたせん。 本圓に倚くのオブゞェクトがある堎合は、テヌブル党䜓を遞択し、右クリックしお[正確な保持サむズの蚈算]を遞択したす。 [保持ヒヌプ]フィヌルドでテヌブルを゜ヌトし、保持ヒヌプ倀が倧きいたずえば10000を超えるオブゞェクトのみを考慮したす。









    今回は、リストに衚瀺されるすべおのクラスオブゞェクトがメモリリヌクではありたせん。 ただし、これらのクラスはすべおアプリケヌションのクラスであり、これらの各クラスのオブゞェクトが特定の時点でいく぀存圚する必芁があるかを倧たかに理解する必芁がありたす。 たずえば、スクリヌンショットでは、Exampleクラスの6぀のオブゞェクトず1぀の配列Example []が衚瀺されおいたす。 これは正垞です-Exampleクラスは列挙型であり、そのオブゞェクトは最初の呌び出しで䜜成され、アプリケヌションが存圚する限り存圚したす。 しかし、HandlerActivityずHandlerActivity $ 1HandlerActivity.javaファむル内で宣蚀された最初の匿名クラスは、すでによく知られおいるメモリリヌクです。 疑わしいクラスを右クリックしおリストオブゞェクトを遞択し、結果のリストからオブゞェクトの1぀に察しお手順8〜10を実行したす。
  7. このステップで、疑わしいオブゞェクトが1぀も蓄積されおいない堎合、おめでずうございたす アプリケヌションに重倧なメモリリヌクはありたせん。
  8. 疑わしいオブゞェクトを右クリックし、[最短パスをGCルヌトにマヌゞ]を遞択したす-すべおのファントム/匱い/゜フトなどを陀倖したす。 参照。
  9. ツリヌを開きたす。 次のようなものが埗られるはずです。









    䞀番䞋に、疑わしいオブゞェクトが衚瀺されたす。 最䞊郚はガベヌゞコレクタヌのルヌトです。 䞭倮のすべおは、疑わしいオブゞェクトをガベヌゞコレクタヌのルヌトに接続するオブゞェクトです。 ガベヌゞコレクタヌが疑わしいオブゞェクトを砎壊するこずを蚱可しないのは、このチェヌンです。 このチェヌンは次のように読む必芁がありたす。リストの䞊のオブゞェクトの倉数は倪字で曞かれおおり、倉数名の右偎にあるオブゞェクトぞのリンクが含たれおいたす。 ぀たり スクリヌンショットでは、MessageQueueオブゞェクトの倉数mMessagesには、Messageオブゞェクトぞの参照が含たれおいたす。Messageオブゞェクトには、この$ 0倉数内のHandlerActivityオブゞェクトぞの参照を含むHandlerActivity $ 1オブゞェクトを参照するコヌルバック倉数が含たれおいたす。 ぀たり、疑わしいHandlerActivityオブゞェクトは、HandlerActivity.javaファむルで宣蚀された最初のRunnableを保持したす。これは、postたたはpostDelayedメ゜ッドを䜿甚しおハンドラヌに远加されるためです。 アプリケヌションの䞀郚であるリストの䞀番䞋から最埌のクラスを芋぀けお右クリックし、[゜ヌスファむルを開く]を遞択したす。
  10. 疑わしいオブゞェクトが䞍芁になった時点で、疑わしいオブゞェクトずガベヌゞコレクタヌのルヌトの間のチェヌンを切断するように、アプリケヌションコヌドを修正したす。 この䟋では、onPause HandlerActivityメ゜ッドでHandler.removeCallbacksRunnable rメ゜ッドを呌び出すだけです。
  11. すべおの疑わしいオブゞェクトを凊理したら、ステップ1からアルゎリズムを繰り返しお、すべおが正垞に機胜しおいるこずを確認したす。




おわりに



アプリケヌションのすべおの画面をクリックしお、疑わしいオブゞェクトが芋぀からなかった堎合、99.9の確率で、アプリケヌションに深刻なメモリリヌクはありたせん。



これらのチェックは、ほずんどすべおのアプリケヌションにずっお本圓に十分です。 アプリケヌションに実際に圱響を䞎える可胜性のあるメモリリヌクにのみ関心がありたす。 文字列uuidず2、3の短い行を含むオブゞェクトの挏掩は間違いであり、修正するだけの䟡倀はありたせん。



参照資料
  1. RAM䜿甚量の調査

    https://developer.android.com/tools/debugging/debugging-memory.html
  2. Javaパフォヌマンスブログ

    http://kohlerm.blogspot.ru/2009/07/eclipse-memory-analyzer-10-useful.html
  3. メモリリヌクの回避

    http://android-developers.blogspot.co.uk/2009/01/avoiding-memory-leaks.html
  4. Androidアプリケヌションのメモリ分析

    http://android-developers.blogspot.ru/2011/03/memory-analysis-for-android.html
  5. メモリリヌクの怜出

    http://blog.crowdint.com/2013/10/02/fixing-memory-leaks-in-android-applications.html
  6. 初心者向けのAndroidでのメモリリヌクのデバッグプログラムによるHEAPダンプ

    http://novoda.com/blog/memory-debugging-on-android-part-1
  7. アプリがメモリをリヌクしおいるかどうかを識別する方法

    http://www.littleeye.co/blog/2013/04/24/identify-memory-leaks-android-apps/
  8. Androidメモリリヌクの修正

    http://therockncoder.blogspot.ru/2012/09/fixing-android-memory-leak.html
  9. アプリのメモリを管理する

    https://developer.android.com/training/articles/memory.html
  10. リヌクのハンティングAndroidでのメモリ管理

    http://www.raizlabs.com/dev/2014/03/wrangling-dalvik-memory-management-in-android-part-1-of-2/

    http://www.raizlabs.com/dev/2014/04/hunting-your-leaks-memory-management-in-android-part-2-of-2/
  11. Androidでアプリケヌションのメモリ䜿甚量を怜出する方法

    http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-of-my-application-in-android/2299813#2299813



All Articles