14
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

LeakCanaryのアラートを調査する

Last updated at Posted at 2017-12-21

ご挨拶

この記事はピクシブ株式会社 AdventCalendar 2017 21日目の記事です。

今年の5月に中途入社した@verno3632と申します。前職ではインフラエンジニアをやりながら、趣味でAndroidアプリを書いていました。非公式アプリを続けていたらいつのまにか入社していました。
現在ではpixivコミックというサービスのチームでAndroidアプリを作っています。KotlinとかDaggerとかArchitecture Componentsとか興味あるものからとりあえず入れてみてます。

今回はLeakCanaryの話です。

LeakCanary

言わずと知れたSquareのライブラリで、入れておくとアプリ実行時にメモリリークを検知して通知してくれます。入れてて当然ですよね?

Logcatを見るまでもなく、Android上だけでどこから何が漏れているのかわかるので非常にありがたい。
ですがシンプルな画面なため詳しい調査には情報が足りないよということがあります。

以下は実際にあったメモリリークです。
Screenshot_20171220-215815.jpg

わかんないよ。

クラス名がリーク元・先として表示されるので、そのクラスを元にあたりをつけていくわけですが、自分で書いたわけではないコードのクラスだったりすると検討がつきません。
ということで調べてみましょう。

Heap Dumpを取得する

メモリの調査をするならまずHeap Dumpです。
最近のAndroidStudioではAndroid Profilerのおかげで簡単にDumpを取ることができるようになりました。

LeakCanaryではHAHAという、これまたSquareのライブラリを使って、Dumpをとっています。
初回起動時にファイル書き込み権限を求められるのも、リークを起こした際に時が止まるのもDumpをとってファイルに吐いているためですね。

Dumpファイルはhprofなので取り出して他ツールで読むことができます。

ファイルの保存場所は、Logcatに以下のようなログが流れてくるのでそこを参考にします。

hprof: heap dump “/storage/emulated/0/Download/leakcanary-${package}/hogehoge.hprof” starting...
hprof: heap dump completed (12MB) in 3.456s objects 789012 objects with stack traces 0

ディレクトリごとまるっと持ってきた方が早いかもしれません。

adb pull /storage/emulated/0/Download/leakcanary-${package}

DumpファイルをAndroid Studioで読み込む

hprofをAndroid Studioで表示するには、プロジェクト直下のcapturesディレクトリにファイルを置きます。
capturesは各種snapshotを置いておくディレクトリで、Layout Inspectorで撮ったキャプチャなどもここに入ってきます。

View > Tool Windows > Capturesを開くと左のWindowからcaptures以下が見えます。

スクリーンショット 2017-12-20 23.04.50.png

リーク元を調べる

hprofファイルを選択するとHPROF Viewer/Analyzerが開きます。

スクリーンショット 2017-12-21 12.16.29.png

まず最初にリークしているインスタンスを探しましょう。
右のWindowのAnalyzer Tasksを実行するのが早いですが、KeyedWeakReferenceのクラスから探すのもありです。KeyedWeakReferenceはLeakCanaryが検知したリーク先への参照を持っています。

次にリーク元を探します。
インスタンスを選択すると下のWindowのReference Treeにそのインスタンスに関する参照が表示されます。
一番下の方にあるreferentを見ると、どこから参照されているかがわかります。

スクリーンショット 2017-12-20 23.29.20.png

RefWatcherはLeakCanaryからの参照なので問題ありません。weakActivityから漏れていますね。
数値計測用に入れていた3rd partyのSDKからでした。

おわりに

LeakCanaryを使ってメモリリークを撲滅し、Picasso/Glideなどのライブラリで画像を扱うことによりOutOfMemoryは以前より格段に減りました。これからも計測・調査を続けてよりよいアプリを作っていきましょう。

ピクシブ株式会社では、クリエイターに向けてサービスを作っていきたいアプリエンジニアを募集しています!

明日は @yensaki です。お楽しみに!

14
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?