Android: largeHeap = "true" соглашение? - программирование
Подтвердить что ты не робот

Android: largeHeap = "true" соглашение?

Я пишу приложение галереи изображений, и у меня все время возникают ошибки памяти. Я кэширую все мои изображения, но проблема возникает, когда я пытаюсь переключиться между изображениями очень быстро. Я предполагаю, что приложение выделяет память быстрее, чем GC имеет время освободить их (потому что авария не происходит, когда я медленно переключаю изображения).

После того, как я ударил головой об этой проблеме в течение нескольких дней, я, наконец, решил попробовать параметр largeHeap в файле манифеста. После этого параметра мое приложение больше не вылетает независимо от того, насколько быстро переключаюсь между изображениями.

Теперь я хочу знать, есть ли какое-либо соглашение или общее руководство для использования параметра largeHeap, потому что это, вероятно, не имеет большого смысла, если, скажем, приложение для заметок, используемое largeHeap. Вообще говоря, какие приложения являются хорошим кандидатом для настройки больших настроек?

Спасибо

4b9b3361

Ответ 1

Вообще говоря, какие приложения являются хорошим кандидатом для установки больших настроек?

В тех случаях, когда вы можете оправдать пользователя, почему вы вынуждаете все свои приложения не использовать память, чтобы дать вам огромное количество кучи.

Лично я не буду рассматривать "приложение галереи изображений" для квалификации. AutoCAD, видеоредакторы и т.д. Будут квалифицированы.

В отношении проблем с управлением памятью убедитесь, что вы используете inBitmap on BitmapOptions при работе на уровне API 11+, поэтому вы перерабатываете существующие буферы, а не просматриваете сбор мусора. В частности, для галереи изображений, где у вас, вероятно, много правильных размеров эскизов, переработка существующих буферов будет огромной выгодой. Это может помочь как общему потреблению памяти (т.е. По-настоящему не хватает памяти), так и фрагментации памяти (т.е. Вы получаете OutOfMemoryError с большим количеством кучи, но ни один блок, достаточно большой для вашего распределения, из-за Android frakkin ' не уплотняющий сборщик мусора).

Вы также можете рассмотреть возможность поиска существующих реализаций кэша изображений, таких как Picasso, чтобы узнать, есть ли какие-то подсказки вы могли бы изучить (или, возможно, просто повторно использовать).

Ответ 2

Во-первых, убедитесь, что вы не загружаете большие растровые изображения, чем необходимо:
Загрузите масштабированную версию в память.


Затем перед попыткой largeHeap попробуйте быстро освободить память:

Если вы вызываете bitmap.recycle();, как только вы уверены, вы не будете использовать растровое изображение снова, тогда основная часть этой растровой памяти будет немедленно освобождена. (Когда GC приближается к нему, все, что остается, является крошечным объектом.)


В новых версиях Android есть альтернативы (вместо recycle), которые могут быть более эффективными:
Управление растровой памятью

Лично я по-прежнему часто использую recycle, особенно если я могу загружать изображение другого размера, поэтому не может reuse существующего. Кроме того, мне легче кодировать "разгрузку" старых носителей отдельно от "загрузки" новых носителей при изменении на другой фрагмент или действие:
Как оставить старый фрагмент, все старые растровые изображения я recycle (тогда, если достижимо из статического поля, установите на null).


Эмпирическое правило о том, следует ли использовать largeHeap, следует рассмотреть после того, как вы попробовали альтернативные способы сокращения использования памяти.

Скомпонуйте свое приложение, чтобы вы могли снова отключить его и все еще работать.

Например, отслеживает использование вашей памяти и загружать "уменьшенные" растровые изображения, если память плотная.. Пользователь действительно заметит, если данное изображение не соответствует разрешению "сетчатки" устройства?

Или, если это более старое, более медленное устройство, будет большойHeap сделать ваше приложение чувствовать себя невосприимчивым/отрывистым? Если да, можете ли вы отбросить разрешение еще дальше или показать меньше растровых изображений за один раз?

Получите ваше приложение для работы во всех обстоятельствах, без largeHeap [по методам, упомянутым выше]. ПРИМЕЧАНИЕ: вы можете "принудительный тест" работать с жесткой памятью, выделив некоторые растровые изображения "dummy" и удерживая ссылки на них в глобальных полях, чтобы они не освобождались.

Теперь вы можете оценить компромисс, так как это влияет на ваше приложение:

Когда вы включите largeHeap, сильно используйте свое приложение - есть ли места, где теперь "более вяло", или анимации "заикаются" или иначе кажутся менее гладкими? УБЕДИТЕСЬ, ЧТОБЫ ТЕСТИРОВАТЬ НА МЕНЬШЕ ОДНОМ ОДНОМ УСТРОЙСТВЕ И НА ОДНОМ ВЫСОКОЙ РЕШЕНИИ. Возможно, вы увидите длинные GC-времена из-за большей кучи.

ИЛИ вы можете заключить, что largeHeap работает хорошо для вас, и теперь вы можете с уверенностью сказать, что это лучший выбор в ваших обстоятельствах.