SoftReference собирает мусор слишком рано - PullRequest
10 голосов
/ 22 апреля 2011

Я на пути к реализации механизма кэширования для моего приложения Android.

Я использую SoftReference, как и многие примеры, которые я нашел.Проблема в том, что при прокрутке вверх или вниз в моем ListView большинство большинства изображений уже очищены.В LogCat я вижу, что мое приложение собирает мусор каждый раз, когда приложение загружает новые изображения.Это означает, что большинство невидимых изображений в ListView исчезли.

Итак, каждый раз, когда я прокручиваю на более раннюю позицию (где я действительно загружал изображения раньше), я должен снова загружать изображения - они не cached .

Я также исследовал эту тему. Согласно Марку Мерфи в этой статье , кажется, что есть (или было?) Ошибка с SoftReference.Некоторые другие результаты указывают на то же самое (или тот же результат);SoftReference s очищаются слишком рано.

Есть ли рабочий раствор?

Ответы [ 4 ]

16 голосов
/ 22 апреля 2011

SoftReference - это кеш бедняков.JVM может поддерживать эти ссылки дольше, но не обязан.Как только нет более жесткой ссылки, JVM может собирать мусор в объекте с мягкой ссылкой.Поведение JVM, с которым вы сталкиваетесь, является правильным, поскольку JVM не нужно дольше удерживать такой объект.Конечно, большинство JVM пытаются до некоторой степени поддерживать живой объект ссылки.

Поэтому SoftReferences - это опасный кеш.Если вы действительно хотите обеспечить кеширование, вам нужен настоящий кеш.Как LRU-кеш .Особенно, если кеширование критично к производительности, вы должны использовать правильный кеш.

7 голосов
/ 13 августа 2012

с сайта Android обучения:

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

В прошлом популярной реализацией кэша памяти была SoftReference или WeakReference, но это не рекомендуется. Начиная с Android 2.3 (API Level 9) сборщик мусора стал более агрессивный сбор мягких / слабых ссылок, что делает их довольно неэффективно . Кроме того, до Android 3.0 (API уровня 11), вспомогательные данные растрового изображения были сохранены в собственной памяти, которая не выпущен предсказуемым образом, потенциально вызывая приложение кратковременно превысить пределы памяти и аварийно завершить работу.

Подробнее в ссылке.

Мы должны использовать LruCache .

2 голосов
/ 22 апреля 2011

Кэшируйте каждое изображение в постоянном хранилище, а не только в памяти.

1 голос
/ 09 июня 2011

Gamlor ответ правильный в вашей ситуации.Однако для получения дополнительной информации см. GC FAQ , вопрос 32.

Виртуальная машина Java HotSpot Server использует максимально возможный размер кучи (который задается параметром -Xmx) длярассчитать оставшееся свободное пространство.

Виртуальная машина Java HotSpot Client использует текущий размер кучи для вычисления свободного пространства.

Это означает, что общая тенденция для серверной виртуальной машины - увеличение кучи, а не увеличение.сбрасывать мягкие ссылки, и поэтому -Xmx оказывает существенное влияние на то, когда мягкие ссылки собираются в мусор.

...