15

私は Android Honeycomb 用に非常にメモリを集中的に使用するアプリケーションを作成してrecycle()Bitmapます。実際、これはアプリケーションがまったく機能するために必要です。これは、Bitmaps が絶えずメモリに出入りするためです。しかし、私は に実装onConfigurationChanged()したばかりActivityなので、(いくつかの理由から) にメモリ解放ルーチンを入れようとしていますonStop()

現在私のonStop()方法:

  • Viewデフォルトを表示するようにいくつかの を設定しますDrawable
  • これらの によって以前に使用されrecycle()た に対する呼び出し。BitmapView
  • sへのヌル参照Bitmap

残念ながら、Eclipse メモリ プロファイラを使用すると、メモリ使用量にはまったく影響がないようです。

ご想像のとおり、名目上はガベージ コレクションが行われる言語でリソースを解放するために多大な努力を払ってきたので、もう少し効果があればと願っていました。だから私の質問は:何をしrecycle()ますか?それは実際にガベージ コレクションをトリガーしますSystem.gc()か? それとも、何かを取り除く必要があると感じるまで、システムはメモリを保持しますか (呼び出したとしても)?

注意: s が実際には通常のヒープに保持されていないことはわかっていますが、ネイティブ ヒープから確実に削除するには呼び出しで十分Bitmapだと思いました。recycle()

答えの一部

にリサイクルされImageViewた が含まれている場合、で が呼び出されるまで、データは引き続きメモリに保持されることがわかりました。これは、またはが呼び出された場合にも当てはまります(それらは比較的小さな 9 パッチでロードされていましたが、MAT 分析では、 のプライベート メンバーに含まれていた大きな が削除されていないことが示されています)。この関数を at で呼び出すだけで、アプリケーションのヒープから約 10 MB が取り除かれました。ただし、これは Android のハニカム以前のビルドには当てはまらないようです。BitmapBitmapsetImageBitmap(null)ImageViewsetImageResource(...)setImageDrawable(...)BitmapImageViewonStop()

4

3 に答える 3

6

Honeycomb以降では、にリサイクルされImageViewたが含まれている場合、ImageViewで呼び出されるまでデータはメモリに保持されることを発見しました。これは、またはが呼び出された場合にも当てはまります(この場合、非常に大きなビットマップがかなり小さな9パッチに置き換えられましたが、9パッチをロードする前に呼び出された場合にのみ、メモリが実際に破棄されました)。BitmapBitmapsetImageBitmap(null)setImageResource(...)setImageDrawable(...)setImageBitmap(null)

于 2011-10-24T10:18:52.147 に答える
6

Justin が言うように、Bitmap データは VM ヒープに割り当てられません。それへの参照は VM ヒープ (小さい) にありますが、実際のデータは基礎となる Skia グラフィックス ライブラリによってネイティブ ヒープに割り当てられます。[これは後の Android レベルで変更されている可能性がありますが、2.1 と 2.2 には当てはまります] VM ヒープの小さな部分とネイティブ ヒープの実際のデータの両方を無料で使用可能としてマークする recycle() を実行すると、 GC。しかし、実際の収集は 2 つの異なる GC メカニズムによって実行されます。VM ヒープの一部は Davlik GC によって収集されます。これは DDMS を介して確認できます。しかし、ネイティブ ヒープ データは Skia GC によって収集されます。つまり、厳密な recycle() を使用しても、ネイティブ ヒープ GC よりも先に進むことができます。幸いなことに、ネイティブ ヒープの状態を監視するメカニズムがあります。見るBitmapFactory OOM は私を夢中にさせます

于 2011-10-21T18:23:18.843 に答える
3

Recycle は、ビットマップに割り当てられているネイティブ メモリを解放します。実際の Bitmap オブジェクトは、次のガベージ コレクションまで Dalvik ヒープに残ります (ただし、このオブジェクトが占有するメモリはわずかです)。

私の知る限り、ネイティブ ヒープをダンプする方法は実際にはありません。そのため、ビットマップのネイティブ データがヒープ ダンプによって失われたかどうかを確認することはできません。ただし、アプリケーションが使用しているメモリの総量が減少していることがわかります。この質問は、アプリのメモリ使用量統計にアクセスするさまざまな方法を見つけるのに役立ちます。

于 2011-10-21T17:27:56.250 に答える