<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
		xmlns:xhtml="http://www.w3.org/1999/xhtml"
>

<channel>
	<title>Bescottee &#187; leak</title>
	<atom:link href="http://andbrowser.com/tag/leak/feed/" rel="self" type="application/rss+xml" />
	<link>http://andbrowser.com</link>
	<description>苦しいときは伸びてるとき、楽なときは伸びていないとき</description>
	<lastBuildDate>Sat, 06 Jan 2018 14:12:26 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://andbrowser.com/tag/leak/feed/" />
		<item>
		<title>メモリリークを発見！Androidアプリのメモリ解析手法　その２ OQL (Object Query Language)利用方法</title>
		<link>http://andbrowser.com/development/knowhow/289/eclipse-android-memory-leak-mat-oql/</link>
		<comments>http://andbrowser.com/development/knowhow/289/eclipse-android-memory-leak-mat-oql/#comments</comments>
		<pubDate>Thu, 18 Aug 2011 10:22:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[KnowHow]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[leak]]></category>
		<category><![CDATA[mat]]></category>

		<guid isPermaLink="false">http://andbrowser.com/?p=289</guid>
		<description><![CDATA[
「メモリリークを発見！Androidアプリのメモリ解析手法」でEclipse Memory Analyzer(MAT)のインストール方法と使い方の紹介をしました。今回は、Eclipse Memory Analyzer  [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://andbrowser.com/wp-content/uploads/2011/08/eclipse-mat.jpg" alt="Eclipse Memory Analyzer (MAT)のサイト画像" title="Eclipse Memory Analyzer (MAT)" width="450" height="300" class="size-medium wp-image-290" align="center" /></p>
<p>「<a href="http://andbrowser.com/development/knowhow/65/eclipse-android-memory-leak-mat/">メモリリークを発見！Androidアプリのメモリ解析手法</a>」でEclipse Memory Analyzer(MAT)のインストール方法と使い方の紹介をしました。今回は、Eclipse Memory Analyzer (MAT)のさらに踏み込んだ使い方を紹介します。</p>
<h4>Eclipse Memory Analyzer(MAT)のインストール方法</h4>
<p>MATがまだインストールしていない場合は、以下の手順でインストールしてください。</p>
<ul>
<li>Eclipseのメニューバーの（日本語化済みの場合）「ヘルプ」⇒「新規ソフトウェアのインストール」
<ul>
<li>作業対象：&#8211;すべての使用可能なサイト&#8211;
<li>フィルター入力：memory
</ul>
<div class="wp-caption alignnone" style="width: 641px"><img src="http://andbrowser.com/wp-content/uploads/2011/08/02.jpg" alt="Memory Analyzer (MAT)インストール画面" title="Memory Analyzer (MAT)インストール画面" width="450" class="size-full wp-image-294" /><p class="wp-caption-text">Memory Analyzer (MAT)インストール画面</p></div>
<li>「Memory Analyzer」 と 「Memory Analyzer(Charts)[オプション]」にチェックをいれて、「次へ」を選択し、インストールを継続
<li>まだ再起動せずに、続いて、 「Memory Analyzer(Charts)[オプション]」で利用する図作成ライブラリ（BIRT)をインストール。これをいれておくとメモリ利用状況がMAT上で綺麗な図で表示されます。是非インストールしておきましょう。<br />
<div id="attachment_296" class="wp-caption alignnone" style="width: 641px"><img src="http://andbrowser.com/wp-content/uploads/2011/08/eclipse-birt..jpg" alt="Memory Analyzer Charts向け図作成ライブラリBIRTインストール" title="Memory Analyzer Charts向け図作成ライブラリBIRTインストール" width="631" height="594" class="size-full wp-image-296" /><p class="wp-caption-text">Memory Analyzer Charts向け図作成ライブラリBIRTインストール</p></div></p>
<li>インストール後は、eclipse 再起動を求められるので、再起動しましょう。
</ul>
<h4>OQL (Object Query Language)利用方法</h4>
<p>Eclipse Memory Analyzer(MAT)には、以下の主要な機能があり、OQLはクラスオブジェクトの任意の抽出方法を定義でできるものです。</p>
<ul>
<li>アクション
<ul>
<li>ヒストグラム(Histgram)：クラスごとのインスタンス数を表示
<li>クラスオブジェクトごとの木構造(Dominator Tree)：もっとも大きなクラスとそれらの存在期間を表示
<li>上位の消費者(Top Consumers)：クラスごととパッケージごとにもっともメモリを利用しているクラスを表示
<li>クラスの複製(Duplicate Classes)：複数のクラスローダからロードされているクラスを発見（レビューコメント頂いたkare様、ありがとうございました）
</ul>
<li>レポート
<ul>
<li>メモリリーク予想(Leak Suspects)：メモリリークの予想とシステム概要をレポート
<li>上位のコンポーネント(Leak Suspects)：全体のヒープの1%よりも大きなコンポーネントをレポートする機能
</ul>
<p>OQL (Object Query Language):は、Javaヒープの検索をするために利用できるＳＱＬのような問い合わせ言語です。OQLはJAVAヒープから必要な情報を選択したり、フィルターしたりすることができます。ＯＱＬは、JavaScrip埋め込み型言語（JavaScript Expression Language)をベースとしています。OQLのクエリー定義は以下のようなものです。</p>
<pre class="brush:java">
select &lt;JavaScript expression to select&gt;
   [ from [instanceof] &lt;class name&gt; &lt;identifier&gt;
   [ where &lt;JavaScript boolean expression to filter&gt; ] ]
</pre>
<p> class name にはフルパスの Javaクラス名（例えば、 java.lang.String）を指定します。</p>
<p>OQLは、以下のMATのメニューから選択できます。<br />
<div id="attachment_311" class="wp-caption alignnone" style="width: 310px"><img src="http://andbrowser.com/wp-content/uploads/2011/08/eclipse-mat-oql-2-300x93.jpg" alt="Eclipse Memory Analyzer(MAT) OQL選択画面" title="Eclipse Memory Analyzer(MAT) OQL選択画面" width="300" height="93" class="size-medium wp-image-311" /><p class="wp-caption-text">Eclipse Memory Analyzer(MAT) OQL選択画面</p></div></p>
<p>OQLは特定のクラスオブジェクト検索を行えるものです。具体例として、100文字以上のString を保持しているオブジェクトを検索したい場合は以下のようなSQLに近いコマンドを実行します。OQLのテキストボックスに以下のコマンドを記載し、「！」ボタンをクリックすると実行されます。</p>
<div id="attachment_313" class="wp-caption alignnone" style="width: 310px"><img src="http://andbrowser.com/wp-content/uploads/2011/08/eclipse-mat-oql-3-300x139.jpg" alt="Eclipse Memory Analyzer(MAT) OQL実行方法" title="Eclipse Memory Analyzer(MAT) OQL実行方法" width="300" height="139" class="size-medium wp-image-313" /><p class="wp-caption-text">Eclipse Memory Analyzer(MAT) OQL実行方法</p></div>
<pre class="brush:sql">
SELECT s FROM java.lang.String s WHERE (s.count >= 100)
</pre>
<p>実行結果は以下のようになります。<br />
<div id="attachment_309" class="wp-caption alignnone" style="width: 310px"><a href="http://andbrowser.com/wp-content/uploads/2011/08/eclipse-mat-oql-1.jpg"><img src="http://andbrowser.com/wp-content/uploads/2011/08/eclipse-mat-oql-1-300x214.jpg" alt="Eclipse Memory Analyzer(MAT)のOQL実行結果" title="Eclipse Memory Analyzer(MAT)のOQL実行結果" width="300" height="214" class="size-medium wp-image-309" /></a><p class="wp-caption-text">Eclipse Memory Analyzer(MAT)のOQL実行結果</p></div></p>
<p>さらに、以下のようなクラスオブジェクトの中身の値も表示することができます。以下の例は、Fileオブジェクトの持っている path フィールドの中身の値を一覧で表示する例です。</p>
<pre class="brush:sql">
select file.path.value.toString() from java.io.File file
</pre>
<p>実行結果は以下のようになります。</p>
<div id="attachment_315" class="wp-caption alignnone" style="width: 310px"><a href="http://andbrowser.com/wp-content/uploads/2011/08/eclipse-mat-oql-4.jpg"><img src="http://andbrowser.com/wp-content/uploads/2011/08/eclipse-mat-oql-4-300x297.jpg" alt="Eclipse Memory Analyzer(MAT) OQL実行例 Fileオブジェクトのpathを表示" title="Eclipse Memory Analyzer(MAT) OQL実行例 Fileオブジェクトのpathを表示" width="300" height="297" class="size-medium wp-image-315" /></a><p class="wp-caption-text">Eclipse Memory Analyzer(MAT) OQL実行例 Fileオブジェクトのpathを表示</p></div>
<p><pre class="brush:sql">
SELECT cl FROM INSTANCEOF java.lang.ClassLoader cl
</pre>
<p>実行結果は以下のようになります。<br />
<div id="attachment_321" class="wp-caption alignnone" style="width: 308px"><img src="http://andbrowser.com/wp-content/uploads/2011/08/eclipse-mat-oql-7-298x300.jpg" alt="Eclipse Memory Analyzer(MAT) OQL実行結果" title="Eclipse Memory Analyzer(MAT) OQL実行結果" width="298" height="300" class="size-medium wp-image-321" /><p class="wp-caption-text">Eclipse Memory Analyzer(MAT) OQL実行結果</p></div></p>
<p>プリミティブ配列を利用する場合は以下のように利用します。</p>
<pre class="brush:sql">
select a from int[] a where a.length >= 256
</pre>
<h4>Android的なOQLの利用方法</h4>
<p>Android開発でOQLを利用する方法としては、まだ良いものは思いついていませんが１つ紹介します。</p>
<p>以下の例は、Activity を継承したクラスの一覧を表示するOQLです。いくつかの画面遷移を行うアプリの場合、ライフサイクルの管理をきちんと行っている前提で、画面遷移した直後やメモリを消費する処理を行った場合にヒープダンプを保存しておいて、後から以下のコメントでどのＡｃｔｉｖｉｔｙが残っているかを調査するのに役立ちます。</p>
<pre class="brush:sql">
SELECT ac FROM INSTANCEOF android.app.Activity ac
</pre>
<p><img src="http://andbrowser.com/wp-content/uploads/2011/08/eclipse-mat-oql-6-300x248.jpg" alt="Eclipse Memory Analyzer (MAT) OQL for Activity" title="Eclipse Memory Analyzer (MAT) OQL for Activity" width="300" height="248" class="size-medium wp-image-319" /></p>
<p>今回のテストで利用したソースは以下です。ボタンを押すと、ActivityContextActivity⇒ActivityContext2Activity⇒ActivityContext3Activity ⇒ActivityContext4Activity の順番にActivityを立ち上げていくのみのサンプルで、ActivityContext4Activityまで画面遷移してから実行した結果です。</p>
<pre class="brush:java">
public class ActivityContextActivity extends Activity {

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public void onClickButton(View v) {
        Intent intent = new Intent(this, ActivityContext2Activity.class);
        startActivity(intent);
    }
}
</pre>
<pre class="brush:xml">
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<Button android:id="@+id/button1" android:text="Button"
		android:layout_height="wrap_content" android:layout_width="match_parent"
		android:onClick="onClickButton"></Button>
</LinearLayout>
</pre>
<h4>OQLを利用してみた感想</h4>
<p>javaの世界では一般的な本ツールも、Androidの世界ではまだ Memory Analyzer ですら利用されていない状況ですが、Eclipse を利用したAndroid開発を進めていくうえで、Eclipse で提供されている JAVA テクノロジーには大変良いものが多く、是非活用していきたいと思っています。OQL以外にもまだまだ利用できるものがありそうなので調べていきたいと思います。</p>
<p>Android開発でMemory Analyzer やOQLの便利使い方をご存じの方は是非コメント頂ければうれしいです。</p>
<div id="wherego_related"><h3>このページを見た人は、以下のページも見ています。</h3><ul><li><a href="http://andbrowser.com/development/knowhow/361/android_market_how_to_update_new_version/" rel="bookmark" class="wherego_title">新しいタイル表示版Android Market の取得方法</a></li><li><a href="http://andbrowser.com/event/2994/android-%E9%96%8B%E7%99%BA%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%8B%89%E5%BC%B7%E4%BC%9A-1/" rel="bookmark" class="wherego_title">Android 開発アンチパターン勉強会 #1</a></li><li><a href="http://andbrowser.com/development/knowhow/712/android-lint/" rel="bookmark" class="wherego_title">Android Lint の利用方法</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://andbrowser.com/development/knowhow/289/eclipse-android-memory-leak-mat-oql/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://andbrowser.com/development/knowhow/289/eclipse-android-memory-leak-mat-oql/" />
	</item>
		<item>
		<title>メモリリークを発見！Androidアプリのメモリ解析手法</title>
		<link>http://andbrowser.com/development/knowhow/65/eclipse-android-memory-leak-mat/</link>
		<comments>http://andbrowser.com/development/knowhow/65/eclipse-android-memory-leak-mat/#comments</comments>
		<pubDate>Sun, 03 Apr 2011 04:50:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[KnowHow]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[leak]]></category>
		<category><![CDATA[mat]]></category>

		<guid isPermaLink="false">http://andbrowser.com/?p=65</guid>
		<description><![CDATA[Androidアプリ開発術の１つである。Androidアプリのメモリ解析手法の紹介です。特にメモリリーク対策が重要。Memory Analysis for Android Applications」の翻訳。]]></description>
			<content:encoded><![CDATA[<p><a href="http://andbrowser.com/wp-content/uploads/2011/04/memory-leak-top.png"><img src="http://andbrowser.com/wp-content/uploads/2011/04/memory-leak-top-1024x682.png" alt="" title="memory-leak-top" width="500"  class="aligncenter size-large wp-image-3339" /></a><br />
<br clear="all"></p>
<p>googleのAndroid開発者向け ブログに「<a href="http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html" target="_blank">Memory Analysis for Android Applications</a>」という記事があったため、自分のために訳しました。参考になれば幸いです。本エントリを見るうえで、eclipse の基本的な使い方を理解している必要があります。</p>
<h1>Androidアプリのメモリ解析手法</h1>
<p>Dalvikランタイムは、ガベージコレクトしてくれるかもしれませんが、それはメモリ管理を行わなくてもよいというわけではありません。モバイル端末上でのメモリ利用状況は特に注意を払わなければなりません。本投稿では、開発するアプリのメモリ利用状況の把握を支援する Android SDK で提供しているメモリプロファイリングツール群のいくつかを紹介させて頂きます。</p>
<p>メモリ利用時の問題はいくつか明らかになっています。例えば、もしあなたのアプリがユーザの画面タッチ操作のたびにメモリリークするとすると、最終的には <span style="color: #008000;">OutOfMemoryError</span> のきっかけになる可能性が高いでしょう。他の問題はもっと複雑で、（あなたのアプリがガベージコレクトが頻繁に発生し、かつ長い時間発生すると）そのアプリと全体のシステムの両方のパフォーマンスを下げる原因になるかもしれません。</p>
<h1>解析・分析のためのツール</h1>
<p>Android SDK はアプリのメモリ利用状況をプロファイリングする手法として、2つの方法を提供します。DDMSの&#8221;Allocation Tracker&#8221;タブとヒープダンプです(heap dums)。Allocation Tracker は、与えられた時間間隔の中で発生しているメモリ割り当ての種類を知りたいときに便利です。Allocation Trackerについてもっと情報が必要な場合は、<a title="Tracking Memory Allocations" href="http://developer.android.com/resources/articles/track-mem.html" target="_blank">Tracking Memory Allocations</a> を見てください。<br />
しかし、それらはアプリケーションヒープの概要の状態に関する情報しか提供されません。本投稿の趣旨は、より強力なメモリ解析・分析のツールであるヒープの表示（dump）にフォーカスをあてていく予定です。</p>
<p>ヒープダンプは、HPROF と言われているバイナリフォーマットの形式で保存されるスナップショット（ある瞬間の情報（点としての情報））です。Dalvik は似たようなフォーマットを利用しますが、<a title="HPROF tool in Java" href="http://java.sun.com/developer/technicalArticles/Programming/HPROF.html" target="_blank">java の HPROF Tool</a>とまったく同じではありません。実行中のAndroidアプリのヒープダンプを生成するいくつかの方法があります。１つは DDMS の HPROF ファイルに保存する機能です。もし、あなたがもっと正確にダンプを作成したいときは<a title="dumpHprofData() Method" href="http://developer.android.com/reference/android/os/Debug.html#dumpHprofData(java.lang.String)" target="_blank">android.os.Debug.dumpHprofData()</a> メソッドを利用してプログラム上からヒープダンプを作成することもできます。</p>
<p>ヒープダンプを解析するために、<a href="http://download.oracle.com/javase/6/docs/technotes/tools/share/jhat.html" target="_blank">jhat</a>や<a title="Eclipse Memory Analyzer (MAT)" href="http://www.eclipse.org/mat/" target="_blank">Eclipse Memory Analyzer (MAT)</a>のような一般的なツールも利用できます。<br />
しなしながら、最初に .hprof(拡張子）ファイルを Dalvik フォーマットから J2SE HPROF フォーマットに変換する必要がでてきます。<br />
そのためにAndroid SDK の中で提供されている <span style="color: #008000;">hprof-conv</span> ツールを利用できます。</p>
<p>たとえば、</p>
<blockquote><p>hprof-conv dump.hprof converted-dump.hprof</p></blockquote>
<p>というコマンドで実行できます。</p>
<h1>例：メモリリークをデバッグする</h1>
<p>Dalvikランタイムの中で、プログラマは明示的にフリーなメモリを割り当てることはできません、そのため　C や C++ の言語のように本当にメモリがリークしているかどうかを知ることができません。</p>
<p>ソースコード上にある&#8221;メモリリーク&#8221;は、不必要に長い間オブジェクトを参照し続けた場合に発生します。たまに 単一参照（single reference)は、大きな（大量な）オブジェクト群のガベージコレクタの実行を妨げることができます。</p>
<p>Android SDKの中にある <a href="http://developer.android.com/resources/samples/HoneycombGallery/" target="_blank">Honeycomb の Gallary Sample アプリ</a>を利用して、実例を用いて理解していきましょう。これは新しいHoneycomb API群のいくつかの使い方を知るためのシンプルな写真閲覧アプリです。</p>
<p>ビルド方法とサンプルコードのダウンロード方法は、<a href="http://developer.android.com/resources/samples/get.html" target="_blank">手順書</a>(Android 開発者サイトのサンプルの取得方法）をご覧ください。</p>
<p>どのようにデバッグできるかの手法を紹介するためにこのアプリに故意にメモリリークを追加しました。</p>
<p><a href="http://1.bp.blogspot.com/-85BU4dyekEk/Uzc926b_KYI/AAAAAAAAAWQ/4durHgt-Lx0/s400/honeycomb-gallery.png"><img alt="" src="http://1.bp.blogspot.com/-85BU4dyekEk/Uzc926b_KYI/AAAAAAAAAWQ/4durHgt-Lx0/s400/honeycomb-gallery.png" title="Debugging a memory leak" class="aligncenter" width="400" height="250" /></a><br />
ネットワーク上から画像を取得するために、このアプリを修正したいと考えてみてください。よりレスポンスをよくするために、最近閲覧した画像を保持するキャッシュの実装を決めたとします。 ContentFragmen.java ファイルにいくつかの小さな変更を行ってみましょう。クラスの上部に新しいスタティック変数を追加しましょう。</p>
<blockquote><p>private static HashMap&lt;String,Bitmap&gt; sBitmapCache = new HashMap&lt;String,Bitmap&gt;();</p></blockquote>
<p>これは、ネットワークからロードするビットマップ群のキャッシュです。続いて <span style="color: #008000;">updateContentAndRecycleBitmap() </span>メソッドをネットワークからロードする前にキャッシュに存在するかどうかの確認を行うために変更し、ロード後にキャッシュにビットマップを追加します。</p>
<pre class="brush:java">    void updateContentAndRecycleBitmap(int category, int position) {
        if (mCurrentActionMode != null) {
            mCurrentActionMode.finish();
        }

        // 描画するためのビットマップを取得し、ImageViewを更新

        // キャッシュにビットマップが存在するかどうかを確認
        String bitmapId = "" + category + "." + position;
        mBitmap = sBitmapCache.get(bitmapId);

        if (mBitmap == null) {
            // キャッシュにない場合、ビットマップをロードし、キャッシュに追加
            // 危険・注意！ 常にビットマップを削除することなしにキャッシュにアイテムを追加
            mBitmap = Directory.getCategory(category).getEntry(position)
                .getBitmap(getResources());
            sBitmapCache.put(bitmapId, mBitmap);
        }
        ((ImageView) getView().findViewById(R.id.image)).setImageBitmap(mBitmap);
    }</pre>
<p>私はここで故意にいれたメモリリークを紹介します。常にキャッシュを削除することなしに ビットマップをキャッシュに追加します。実際にアプリでこのような実装する場合は、いくつかの方法でキャッシュサイズに制限をかけたいを考えるでしょう。</p>
<h1>DDMSを利用してヒープの利用状況を確認</h1>
<p>Dalvik Debug Monitor Server (DDMS) は、主要なAndroidデバッグツールの１つです。DDMSは <a href="http://developer.android.com/sdk/eclipse-adt.html" target="_blank">ADT Eclupse プラグイン</a>の一部で、単体動作版はAndroid SDKの <span style="color: #008000;">tools/</span> ディレクトリの中にあります。DDMSに関する情報をもっと知りたい場合は、<a href="http://developer.android.com/guide/developing/debugging/ddms.html" target="_blank">DDMSを利用</a>してみましょう。</p>
<p>それでは、このアプリのヒープ利用状況を確認するためにDDMSを利用しましょう。DDMSを起動する方法は2つあり、そのどちらでも起動できます。</p>
<ul>
<li>Eclipse上からメニューバーを以下の順序で選択する方法</li>
</ul>
<p style="padding-left: 60px;">Windows &gt; Open Perspective &gt; Other &#8230; &gt; DDMS</p>
<ul>
<li>コマンドライン上から <span style="color: #008000;">tools/</span> ディレクトリの中にある <span style="color: #008000;">ddms </span>を起動する。</li>
</ul>
<p style="padding-left: 60px;">（追記：Windowsの場合は、ddms.bat が起動され、Mac/Linux の場合は、ddmsが起動される。（それぞれに PATH を通している必要があります））</p>
<p><a href="http://2.bp.blogspot.com/-DCj7FoBepAQ/Uzc9u18ARPI/AAAAAAAAATU/jOHOLCGsKCw/s1600/ddms-toolbar.png"><img alt="" src="http://2.bp.blogspot.com/-DCj7FoBepAQ/Uzc9u18ARPI/AAAAAAAAATU/jOHOLCGsKCw/s1600/ddms-toolbar.png" title="Examing heap usage in DDMS-1" class="aligncenter" width="400" height="312" /></a></p>
<p>左のパネルから<span style="color: #008000;">com.example.android.hcgallery</span>プロセスを選択して、ツールバー上の&#8221;Show heap updates&#8221;ボタンをクリックします。<br />
それから DDMS の VM Heap タブに切り替えます。</p>
<p>ヒープメモリ利用状況について GC毎に更新されるいくつかの基本情報が見れます。最初の更新を行うために、&#8221;Cause GC&#8221;ボタンをクリックします。</p>
<p><a href="http://1.bp.blogspot.com/-iYqRtBzuPEw/Uzc9uqm3yyI/AAAAAAAAATY/RJQm-z0ySUI/s1600/ddms-heap-usage.png"><img alt="" src="http://1.bp.blogspot.com/-iYqRtBzuPEw/Uzc9uqm3yyI/AAAAAAAAATY/RJQm-z0ySUI/s1600/ddms-heap-usage.png" title="Examining heap usage in DDMS-2" class="aligncenter" width="400" height="212" /></a></p>
<p>我々は live setという（割り当てメモリ列）8MBを少し超えるものをみることができます。サンプルアプリの写真をフリックすると、数字が増加していくのが見れます。このアプリは13枚の写真しかありませんが、リークしたメモリの容量が割り当てられていきます。このような場合リークの最悪のパターンが訪れます。しかしながら我々は決して リークすることにより <span style="color: #008000;">OutOfMemoryError</span> を起こしてはいけません。</p>
<h1>ヒープダンプ(heap dumps)を作成</h1>
<p>問題を追うためにヒープダンプを作ってみましょう。DDMSツールバーのDump HPRPF fileボタンをクリックして、保存場所を選択して、それから <span style="color: #008000;">hprof-conv</span> でコンバートしてください。この例では、MAT(Ver 1.0.1)のスタンドアローンバージョン(Stand alone version)を利用しています。これは<a href="http://www.eclipse.org/mat/downloads.php" target="_blank">MATダウンロードサイト</a>で提供されています。</p>
<p>もし、ADT(DDMSのプラグインの親元)が実行している場合や Eclipse に MAT がインストールされている場合は、&#8221;dump HPROF&#8221;ボタンを押すと自動的にコンバート（hprof-convを実行）してくれ、Eclipse内（MATでオープンされる）で変換された hprof ファイルを開いてくれます。</p>
<h2>MATを利用したヒープダンプの解析・分析</h2>
<p>MATを実行し、いま先ほど作成したコンバート済みの HPROF ファイルをロードしてください。（上記のように必要なツールがインストールされていれば、自動的にコンバートとMAT起動を行ってくれます）。MATは強力なツールですべての機能を説明するためには本投稿の範囲を超えてしまいます。そのためいまはリークを発見するために利用する１つの方法として、Histogram View（ヒストグラムビュー）を紹介します。ヒストグラムビューはインスタンスの数でソートされたクラスのリストと表面上のヒープ（表層ヒープ：shallow heap）（すべてのインスタンスで利用しているメモリの総合計）と保持されたヒープ（保持ヒープ：retained heap）（他のオブジェクトへの参照をもっているオブジェクトを含めたすべてのインスタンスで生きているメモリの総合計）を表示します。</p>
<p><a href="http://1.bp.blogspot.com/-GUy6M0jJnfw/Uzc9-4mMptI/AAAAAAAAAZA/J3mxtLxH014/s1600/mat-references.png"><img alt="" src="http://1.bp.blogspot.com/-GUy6M0jJnfw/Uzc9-4mMptI/AAAAAAAAAZA/J3mxtLxH014/s1600/mat-references.png" title="analyzing heap dump using MAT-1" class="aligncenter" width="400" height="316" /></a></p>
<p>もし shallow heap でソートすれば、<span style="color: #008000;">byte配列</span>のインスタンスが上部に表示されます。Android 3.0(ハニカム）の場合、ビットマップオブジェクトのピクセルデータは <span style="color: #008000;">byte配列</span>に保存されます。（以前は Dalvik heap に保存されませんでした）<br />
そして、それらのオブジェクトのサイズを参考にして、メモリリークしたビットマップのための裏にあるメモリだと賭けても(bet)あっている(safe)でしょう。</p>
<p>byte[] クラス上で右クリックで押して、<br />
List Objects → incoming references<br />
を選択します。これは、ヒープの中に byte 配列のすべてをリストで表示したもので、Shallow Heapの利用状況をベースにソートすることのできます。</p>
<p>大きなオブジェクトの一つを選び、ドリルダウンしていきましょう。これは、オブジェクトのrootからの path を見せてくれます。生存しているオブジェクト参照のつながりを表しています。ほら、我々のビットマップキャッシュがありますね。</p>
<p><a href="http://1.bp.blogspot.com/-GUy6M0jJnfw/Uzc9-4mMptI/AAAAAAAAAZA/J3mxtLxH014/s1600/mat-references.png"><img alt="" src="http://1.bp.blogspot.com/-GUy6M0jJnfw/Uzc9-4mMptI/AAAAAAAAAZA/J3mxtLxH014/s1600/mat-references.png" title="analyzing heap dumps using MAT-2" class="alignnone" width="400" height="316" /></a></p>
<p>MATはこれがリークかどうかを教えてはくれません。なぜなら、それが必要なものか、そうでないかがわからないためです。それはプログラマのみができることなのです。今回の場合、キャッシュは比較的アプリの休憩中（ユーザが操作していない場合）にメモリの大きな容量を使っています。そのためキャッシュのサイズの上限を検討しないといけません。</p>
<h1>MATでヒープダンプを比較</h1>
<p>メモリリークをデバッグしているとき、2つの異なったポイントのヒープ利用状況を比較すると、とても有益です。それを行うために、2つの異なる HPRPOF ファイルを作成する必要があります。（<span style="color: #008000;">hprof-conv</span>を使ってコンバートは忘れずに！）</p>
<p>では、ここでどうやって MAT で2つのヒープダンプを比較すればよいかをお伝えします。（少し重ねればよいのです）</p>
<ol>
<li> 最初のHPROFファイルを開く（Fie &gt; Open Heap Dump)</li>
<li> ヒストグラムビュー(Histogram view)を開く</li>
<li> Navigation History view（eclipe のメニューのWindow &gt; Navigation History。なければ Window &gt; Other&#8230; &gt; Memory Analyzer Views &lt; Navigation Historyで選択）の中の histogram を選択し、右クリックして「Add to Compare Basket」を選ぶ</li>
<li>2つ目の HPROF ファイルをステップ2と3を繰り返してください</li>
<li>「Compare Basket view」に切り替えて、Compare the Results（Compare Basket viewの上部の右上にある赤い！アイコン）をクリック</li>
</ol>
<h1>結論</h1>
<p>本投稿ではどのように allocation Tracker と ヒープダンプ(heap dumps)はアプリのメモリ利用状況のよりより見え方・感じ方を得るための方法を紹介しました。私はまた どのよに Eclipse Memory Analyzer(MAT) がアプリのメモリリークを追う方法を紹介しました。MATは強力なツールであり、私もこのツールで何ができるかの表面しか紹介しませんでした。</p>
<p>もしあなたがよりもっと学びたいとお考えなら、以下のURLのいくつかを読むことをお勧めします。</p>
<ul>
<li><a href="http://dev.eclipse.org/blogs/memoryanalyzer/" target="_blank">Memory Analyzer News</a>（英語）
<ul>
<li>Eclipse MAT プロジェクトの公式ブログ</li>
</ul>
</li>
</ul>
<ul>
<li> <a href="http://kohlerm.blogspot.com/" target="_blank">Markus Kohler&#8217;s Java Performance blog</a>（英語）
<ul>
<li>多くの役に立ち記事があります。ここには <a href="http://kohlerm.blogspot.com/2010/02/android-memory-usage-analysis-slides.html" target="_blank">Eclipse Memory Analyzer を利用したAndroidアプリのメモリ利用分析</a>があったり、<a href="http://kohlerm.blogspot.com/2009/07/eclipse-memory-analyzer-10-useful.html" target="_blank">Eclipse Memory Analyzerのための10個の役に立つ開発術</a>があります。</li>
</ul>
</li>
</ul>
<h1>メモリリークを避けるためにお薦め本</h1>
<table>
<tbody>
<tr>
<td style="border-style: none;"><a href="http://www.amazon.co.jp/gp/product/489471499X/ref=as_li_tf_il?ie=UTF8&amp;tag=andbrowser001-22&amp;linkCode=as2&amp;camp=247&amp;creative=1211&amp;creativeASIN=489471499X"><img src="http://ws.assoc-amazon.jp/widgets/q?_encoding=UTF8&amp;Format=_SL110_&amp;ASIN=489471499X&amp;MarketPlace=JP&amp;ID=AsinImage&amp;WS=1&amp;tag=andbrowser001-22&amp;ServiceVersion=20070822" border="0" /></a><img src="http://www.assoc-amazon.jp/e/ir?t=andbrowser001-22&amp;l=as2&amp;o=9&amp;a=489471499X" border="0" width="1" height="1" style="border: none !important; margin: 0px !important;" /></td>
<td style="border-style: none;"><a href="http://www.amazon.co.jp/gp/product/489471499X/ref=as_li_tf_tl?ie=UTF8&amp;tag=andbrowser001-22&amp;linkCode=as2&amp;camp=247&amp;creative=1211&amp;creativeASIN=489471499X">Effective Java 第2版</a></p>
<p>まだお持ちでないなら、メモリリークを避けるためにも必読です。</td>
</tr>
<tr>
<td style="border-style: none;"><a href="http://www.amazon.co.jp/gp/product/4797327030/ref=as_li_tf_il?ie=UTF8&amp;tag=andbrowser001-22&amp;linkCode=as2&amp;camp=247&amp;creative=1211&amp;creativeASIN=4797327030"><img src="http://ws.assoc-amazon.jp/widgets/q?_encoding=UTF8&amp;Format=_SL110_&amp;ASIN=4797327030&amp;MarketPlace=JP&amp;ID=AsinImage&amp;WS=1&amp;tag=andbrowser001-22&amp;ServiceVersion=20070822" border="0" /></a><img src="http://www.assoc-amazon.jp/e/ir?t=andbrowser001-22&amp;l=as2&amp;o=9&amp;a=4797327030" border="0" width="1" height="1" style="border: none !important; margin: 0px !important;" /></td>
<td style="border-style: none;"><a href="http://www.amazon.co.jp/gp/product/4797327030/ref=as_li_tf_tl?ie=UTF8&amp;tag=andbrowser001-22&amp;linkCode=as2&amp;camp=247&amp;creative=1211&amp;creativeASIN=4797327030">増補改訂版Java言語で学ぶデザインパターン入門 </a><img src="http://www.assoc-amazon.jp/e/ir?t=andbrowser001-22&amp;l=as2&amp;o=9&amp;a=4797327030" border="0" width="1" height="1" style="border: none !important; margin: 0px !important;" /></p>
<p>先人の知恵であるパターンを利用することによって大幅にメモリリークを避けられるようになります。</td>
</tr>
<tr>
<td style="border-style: none;"><a href="http://www.amazon.co.jp/gp/product/4797331623/ref=as_li_tf_il?ie=UTF8&amp;tag=andbrowser001-22&amp;linkCode=as2&amp;camp=247&amp;creative=1211&amp;creativeASIN=4797331623"><img src="http://ws.assoc-amazon.jp/widgets/q?_encoding=UTF8&amp;Format=_SL110_&amp;ASIN=4797331623&amp;MarketPlace=JP&amp;ID=AsinImage&amp;WS=1&amp;tag=andbrowser001-22&amp;ServiceVersion=20070822" border="0" /></a><img src="http://www.assoc-amazon.jp/e/ir?t=andbrowser001-22&amp;l=as2&amp;o=9&amp;a=4797331623" border="0" width="1" height="1" style="border: none !important; margin: 0px !important;" /></td>
<td style="border-style: none;"><a href="http://www.amazon.co.jp/gp/product/4797331623/ref=as_li_tf_tl?ie=UTF8&amp;tag=andbrowser001-22&amp;linkCode=as2&amp;camp=247&amp;creative=1211&amp;creativeASIN=4797331623">増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編 </a><img src="http://www.assoc-amazon.jp/e/ir?t=andbrowser001-22&amp;l=as2&amp;o=9&amp;a=4797331623" border="0" width="1" height="1" style="border: none !important; margin: 0px !important;" /></p>
<p>マルチスレッド環境ではメモリリークが発生しやすくなります。マルチスレッドを扱う場合は必読です。</td>
</tr>
</tbody>
</table>
<p><script type="text/javascript">// <![CDATA[
 google_ad_client = "ca-pub-1843419744371828"; /* androidメモリリーク横長 */ google_ad_slot = "9590468322"; google_ad_width = 468; google_ad_height = 60;
// ]]&gt;</script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript">
</script></p>
<div id="wherego_related"><h3>このページを見た人は、以下のページも見ています。</h3><ul><li><a href="http://andbrowser.com/development/3583/hvc-c2wsdk/" rel="bookmark" class="wherego_title">家族目線(HVC-C2W)SDKのAndroid版サンプルアプリ利用方法</a></li><li><a href="http://andbrowser.com/development/knowhow/712/android-lint/" rel="bookmark" class="wherego_title">Android Lint の利用方法</a></li><li><a href="http://andbrowser.com/uncategorized/3523/git-config-alias-fetch-pullsfetch-origin-refspullrefsremotespull/" rel="bookmark" class="wherego_title">git config alias.fetch-pulls=fetch origin +refs/pull/*:refs/remotes/pull/*</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://andbrowser.com/development/knowhow/65/eclipse-android-memory-leak-mat/feed/</wfw:commentRss>
		<slash:comments>120</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://andbrowser.com/development/knowhow/65/eclipse-android-memory-leak-mat/" />
	</item>
	</channel>
</rss>
