メモリリークの確認方法
今回は、以前から気になっていたAndroidでのメモリリークに関して。
Bitmapを扱う部分など、ドキドキしていたので、今回しっかりとメモリダンプの取得方法を勉強してみました。
今回は、DDMSを使って取得しています。
やり方は、下記の通りです。
- まず、DDMSを立ち上げ、Devicesのタブからヒープメモリを取得したいアプリ(パッケージ名)を選択します。
- 選択した状態で、そのすぐ上にある"Update Heap"のアイコンを押します。これで、ヒープメモリの取得が始まります。
- トラックしたいアプリを立ち上げ、操作します(ここは確認したいシナリオに応じて操作が異なりますね)
- 終了したら、アプリを抜けます。僕は何となくBackキーで抜けるように(ちゃんとonDestroyが走るように)しています。
- DDMSに戻り、"Heap"のタブを選択、"Cause GC"のボタンを押し、ガベージコレクションを走らせます(この段階でGCで解放されなかったメモリが、メモリリークとなります)
- 続いて、"Devices"のタブに戻り、"Dump HPROF File"のボタンを押します。こうすると、ヒープメモリの情報がHPROF形式で出力されます。
- hprof-convコマンドを使って、標準のhpof形式のファイルを作成します。hprof-convコマンドは、Android SDKの中にあります。(僕の場合は、tools以下にありました)コマンドは、
hprof-conv xxx.xxx.xxx.hprof(xxx.xxx.xxx.hprofは先ほど出力されたもの) yy.hprof
です。
- 続いて、jhatコマンドで、その内容を表示します。
jhat yy.hprof
とやると、内部でローカルサーバが立ち上がります。
- http://localhost:7000/にアクセスすると、ヒープの内容が確認できます。
- ここから、確認したいアプリのパッケージ名を探します(クラスごとに表示されるので、大量に表示されるかと思います)
- 該当するクラスを選択して別ページに遷移後、"Reference to this object"の項目にリンクがあるものが、メモリリークです。これをやっつけましょう。
- どこから参照されているためにリークしているかを確認するためには、"excludes weak refs"のリンクをクリックし、次のページに遷移します。
- ここで、Static referenc from "xxx.xxx.xxx.(クラス名)”となっているものが原因です。ここを修正しましょう。
とりあえずこんな感じ。
他のアプリもついでに確認しましたが、結構バイト単位ではリークしていたりで、
一昔前の組み込みでもないので、そこまで厳密にやらなくてもいいかも・・・という気はしますが、
知っておいて損はないものだと思うので、備忘録の意味もかねて書きました。
何か違うよー、などありましたらご指摘くださいませ。
※本当はスクリーンショットをつけた方がわかりやすいんでしょうが、何せ面倒で。。。