10

Android アプリケーションにキャッシュ メカニズムを実装しようとしています。

SoftReference私が見つけた多くの例のように、私は を使用します。問題は、 で上下にスクロールするListViewと、ほとんどの画像がすでにクリアされていることです。アプリケーションが新しい画像をロードするたびに、アプリケーションがガベージ コレクションされていることを LogCat で確認できます。これは、目に見えない画像のほとんどListViewがなくなったことを意味します。

そのため、スクロールして前の位置 (以前に実際に画像をダウンロードした場所) に戻るたびに、画像をもう一度ダウンロードする必要があります。画像はキャッシュされていません

私もこのトピックについて調査しました。この記事の Mark Murphy によると、 にはバグがある (またはあった?) ようですSoftReference。他のいくつかの結果は、同じこと (または同じ結果) を示しています。SoftReferences がクリアされるのが早すぎます。

実用的な解決策はありますか?

4

5 に答える 5

16

SoftReference は貧乏人のキャッシュです。JVM はこれらの参照をより長く保持できますが、そうする必要はありません。ハード参照がなくなるとすぐに、JVM はソフト参照されたオブジェクトをガベージ コレクションできます。JVM はそのようなオブジェクトを長く保持する必要がないため、発生している JVM の動作は正しいです。もちろん、ほとんどの JVM はソフト参照オブジェクトをある程度存続させようとします。

したがって、SoftReferences は一種の危険なキャッシュです。本当にキャッシュ動作を確実にしたい場合は、実際のキャッシュが必要です。LRU-cacheのように。特に、キャッシングがパフォーマンスにとって重要な場合は、適切なキャッシュを使用する必要があります。

于 2011-04-22T17:18:17.527 に答える
7

Android トレーニング サイトから:

http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

以前は、一般的なメモリ キャッシュの実装は SoftReference または WeakReference ビットマップ キャッシュでしたが、これはお勧めできません。Android 2.3 (API レベル 9) 以降、ガベージ コレクターはより積極的にソフト/ウィーク参照を収集するため、 かなり効果がなくなります。さらに、Android 3.0 (API レベル 11) より前のバージョンでは、ビットマップのバッキング データがネイティブ メモリに格納されていたため、予測可能な方法で解放されなかったため、アプリケーションが一時的にメモリ制限を超えてクラッシュする可能性がありました。

詳細はリンク先をご覧ください。

代わりにLruCacheを使用する必要があります。

于 2012-08-13T10:46:16.827 に答える
2

メモリだけでなく、永続ストレージに各イメージをキャッシュします。

于 2011-04-22T17:17:34.683 に答える
1

あなたの状況では、Gamlorの答えは正しいです。ただし、追加情報については、GC FAQの質問 32 を参照してください。

Java HotSpot Server VM は、可能な最大ヒープ サイズ (-Xmx オプションで設定) を使用して、残りの空き領域を計算します。

Java HotSpot クライアント VM は、現在のヒープ サイズを使用して空き領域を計算します。

これは、サーバー VM がソフト参照をフラッシュするのではなく、ヒープを拡大するという一般的な傾向があることを意味します。したがって、-Xmx は、ソフト参照がガベージ コレクションされるタイミングに大きな影響を与えます。

于 2011-06-09T18:26:14.917 に答える