Android 4.4では、メモリプロファイルの解析が簡単に行える開発者オプションが追加されました。Android 4.4搭載端末で[設定]→[開発者向けオプション]→[プロセスの統計情報]で、端末上で開発者のアプリやサービスがどれぐらいメモリを使用しているかの確認が簡単に行えます。
筆者は、この画面を確認して、負荷が高いアプリを幾つかアンインストールしました。不用意にサービスを常駐させたり、高付加な処理を長時間行わせたりすると、この画面でそうした傾向が顕著に現れるため、アンインストールの契機となってしまうことに気を付けなければなりません。
このプロセスの統計情報は、前述したprocstatsサービスで収集されたデータを分かりやすく表示する機能です。メニューから統計情報の期間(3時間、6時間、12時間、1日)を変更できるため、メモリ使用量やプロセスの実行時間の推移が大まかには分かります。
ただし、直近のデータしか表示できず、また1時間ごとの推移などは可視化できないため、必要に応じてprocstatsを使うとよいでしょう。
Androidの主要要素技術であるDalvik VMは、当初からスマートフォン向けのVMとして省メモリを軸に設計されてきました。アプリやサービスは、共通のライブラリが初期化された状態の「Zygote」というプロセスからフォークされ、可能な限り全プロセスでメモリ空間を共有します。
AndroidのActivityやServiceのライフサイクルも、限りあるメモリを複数のプロセス(アプリ)で使えるようにするために、ローメモリ通知やプロセスが終了されて、フォアグラウンドのプロセスにメモリ空間を開け渡せるように設計されています。それぞれのプロセスの初期ヒープは少なめに確保し、必要に応じてmmapやashmemなどの仕組みでヒープが成長するようになっています。
この“ヒープの成長”は、具体的にどのようになっているのでしょうか。
あるアプリが起動し、インスタンスをどんどん生成していくとします。そしてヒープ使用量が初期ヒープサイズまで到達し、これ以上インスタンスを生成できない状態になると、GC(ガベージコレクション)が実施され、不要なインスタンスを回収してヒープに空きを作ります。このGCでも空きができない場合、ヒープが初期サイズを超えて成長します。
これを繰り返してヒープの最大サイズまで到達し、かつGC後にインスタンスを生成する空きがなくなると、OutOfMemoryErrorが発生します。
アプリがOutOfMemoryErrorを発生させないようにするには、どのようにすればよいのでしょうか。
Dalvik VMのGCのアルゴリズムは、コンカレントマーク&スイープです。マーク&スイープは、GCを繰り返すことでヒープから連続したメモリ領域が徐々になくなってしまうというフラグメントが発生します。
フラグメントが発生したヒープは、例えば空きは100KBあるにもかかわらず、10KBの連続領域が存在しない、という事態に陥ってしまうことがあります。
つまり、どのように気を付ければよいかというと、以下のようなことが考えられます。いずれも速度が犠牲になりそうなので、悩ましいところではありますが。
Android 4.4で追加、強化されたメモリ使用状況を把握するためのツールを掘り下げてみました。procstatsやmeminfoはコマンドを見て分かる通り「dumpsys」コマンドの機能の一部です。
Androidのコマンドラインツールは画面を動画としてキャプチャしたり、モンキーテストを行ったりする一風変わったオプションが用意されています。次回はコマンドラインツールの基本と応用について解説する予定です。
Copyright © ITmedia, Inc. All Rights Reserved.