デバッグ中、何か良からぬ挙動を発見した時に、怪しげなオブジェクトの持っている状態がどうなっているかを調べる場合において、デバッガをアタッチして調べることが困難なことがあります。例えば、その怪しい挙動に再現性のない場合を考えてみると、再度同じ挙動を起こすまでに膨大な時間が必要になるかもしれません。そもそも、どこが悪いのかも分からないのに無闇にデバッガをアタッチしていては、検証にかかる時間が無駄に伸びてしまう可能性もあります。
この記事では、怪しい挙動を発見した瞬間に、デバッガに頼らずともオブジェクトの持っている状態がどうなっているかを調べたい人のための手順をまとめます。
AndroidStudio でヒープダンプを取る
AndroidStudio には、それぞれのプロセスがどのくらいメモリや CPU、GPU のリソースを消費しているかを可視化してくれるツールが組み込まれています。普段 Logcat を使うことが多いかもしれませんが、画面下部の Android Monitor というメニューの中に、Logcat 以外に「メモリ」「CPU」「GPU」「ネットワーク」のタブがあり、それぞれ、見てみたいプロセスごとにグラフが表示されるようになっています。
横軸は時間ですので、放っておくとグラフが流れていきます。
このグラフ、実は単にメモリ使用量の様子を可視化してくれるだけではありません。このグラフの左側を見ると、幾つかのボタンが有ることがわかります。
この内、下矢印のついている上から 3 番目のボタンが、ヒープダンプを取るためのボタンになります。
ヒープダンプを取ってみると、ボタンのアイコンがグラフ上に現れます。
このアイコンが表示されたタイミングのヒープダンプが取得できたことがわかります。
ヒープダンプから、状態を調べたいクラスを探す
ヒープダンプが終わると、hprof ファイルが自動で開かれます。
デフォルトでは、アプリケーションのヒープにある各クラスの一覧が表示されるはずです。
ここでどれかひとつクラス名をクリックしてみると、ヒープに乗っているインスタンスの一覧が右側に表示されます。
インスタンスの一覧を展開して、それぞれの状態を調べる
インスタンス一覧のどれかひとつをクリックすると、リストが展開され、そのインスタンスの内部の様子が表示されます。
これで、そのインスタンスの状態がどうなっているかを覗き見ることが出来ました。あとは、どのプロパティが不正な値になっているかを調べたりすることで、おかしな挙動を見つけていくことになります。
目的のクラスにたどり着くまでの方法
幾つか方法があります。
- クラス名一覧にフォーカスを当て、見たいクラス名をタイプする
AndroidStudio では、いたるところで直接文字列をタイプして検索をかけることが出来るようになっています。プロジェクトパネルにフォーカスがある場合は、各モジュールの中から文字列に一致する部分をハイライトしてくれたりします。これと同じ要領で、ヒープダンプのクラス一覧から対象のクラスを探しだすことが出来ます。 - クラス一覧の表示をパッケージごとに切り替えて探す
クラス一覧の他に、パッケージ一覧の表示もできるようになっています。クラス一覧の上にある「Class List View」の部分を、「Package List View」に切り替えれば簡単に表示が変えられます。
まとめ
ヒープダンプと言うと、どうしてもメモリリークの調査に主眼をおきがちになりますが、AndroidStudio を使えば、メモリに乗っているオブジェクトの状態も見ることが出来ます。もちろん、どうしてそういう状態になったのかを調べるためには、デバッガをアタッチして状態の変化するところにブレイクポイントを張り、変化した時のスタックトレースをみるなどの方法も重要ではありますが、そもそも何がどう悪くなっているかを調べるには、ヒープダンプを活用するほうがいくらか手軽にできます。
さいごに
今年も一年お疲れ様でした。来年も良い年でありますように🙏