4月 06

androidAndroid Developers BlogよりAvoiding memory leaksを読んで、個人的備忘録(なので、正確さは無保証です)。

# 追記:Android Zaurusさんのところに全訳がありました

不要な参照をしていると、期待通りにGCでメモリが解放されない(ここではこれをメモリリークと呼んでいる)わけだけど、Androidでは注意すべきところがある。

AndroidではいろいろなオブジェクトがContextという引数を取る。通常は現在のActivityを渡すのだが、これによりActivityが予想外に解放されなくなることがある。Activityは割と頻繁に生成/廃棄されるので(例えば縦横切り替えとか)これは問題だ。

例えば、Drawableはロード時間かかるのでアプリケーションでキャッシュしておきたくなる。ところが、DrawableはonCallbackのためにViewを参照しており、そのViewはContextとしてActivityを参照している。したがって、Drawableが生きているあいだはActivityが解放されなくなる。Homeではこれを回避するために、icon.setCallback(null)としていたりする。

こんなことにならないためには、Contextをそのスコープ外で参照しないようにする、また、アプリケーションで共通に利用するオブジェクトにはContext.getApplicationContext()やActivity.getApplication()を使って、ApplicationをContextとして渡してあげればよい。

覚えておくべきこと

  • ActivityをContextとして長期間(Activityのライフサイクルを超えて)保持してはいけない
  • 長期間保持するようなときにはApplicationをContextに使おう
  • Activityのライフサイクルを制御できないときは、Activity内では非静的な内部クラスを避ける。静的な内部クラスを使って、そのActivityへの弱い参照を使うとよい(弱い参照だけだとGCの対象になるため)
  • GCがあるからといって、メモリーリークが起こらないわけではない


2 Responses to “Androidでのメモリリーク回避”

  1. androidzaurus より:

    そのエントリ、以前、ざくっと訳してみました。ご参考まで。
    http://d.hatena.ne.jp/androidzaurus/20090121/1232519066

  2. sasai より:

    リンクはらせて頂きました、ありがとうございます。

Leave a Reply

preload preload preload
QLOOKアクセス解析