Android: как увеличить размер кучи во время выполнения? - PullRequest
16 голосов
/ 07 ноября 2010

В моем приложении есть кеш изображений, который реализован с использованием SoftReferences.Dalvik запускает приложения с относительно небольшой кучей, а затем увеличивает ее в случае необходимости.Но я бы хотел, чтобы размер моей кучи был больше с самого начала.Это связано с тем, что, когда у меня уже есть несколько изображений в кеше, и начинается какое-либо действие (например), или возникает другое пиковое требование к памяти, мой кэш очищается, чтобы освободить память для этого пикового спроса.В результате, после того, как пик прошел, у меня все еще остается 2-3 МБ свободного места, но мой кэш пуст!

Решение, которое я вижу для этой проблемы, заключается в предварительном выделении заранее большой кучи, так что даже спиковое потребление составляет 2-3 МБ, у него все еще есть пространство, поэтому мои SoftReferences не удаляются.

Я обнаружил, что VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE) было бы полезно.В частности, Google использует это в своих приложениях, как упоминалось здесь .Однако класс VMRuntime помечен как устаревший и, как утверждается, будет удален из общедоступного API в следующем выпуске.Так что setMinimumHeapSize не является постоянным решением.

Как тогда я заставлю Dalvik вырастить кучу при запуске?

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

Ответы [ 5 ]

6 голосов
/ 23 января 2013

Вместо увеличения размера кучи вы можете сделать что-то лучше.Как вы сказали, вы поддерживаете кеш в вашем приложении, которое реализовано с помощью SoftReferences.Лучше всего использовать LruCache, вы можете сделать что-то вроде этого:

private LruCache<String, Bitmap> bitmapCache;
final int memClass;
int cacheSize;

memClass = ((ActivityManager) context.getSystemService(
    Context.ACTIVITY_SERVICE)).getMemoryClass();

Возвращает приблизительный класс памяти для приложения текущего устройства.Это дает вам представление о том, какой жесткий лимит памяти вы должны наложить на свое приложение, чтобы обеспечить оптимальную работу всей системы.Возвращаемое значение в мегабайтах;базовый класс памяти Android равен 16 (что является пределом кучи Java для этих устройств);некоторые устройства с большим объемом памяти могут возвращать 24 или даже более высокие числа.

cacheSize = 1024 * 1024 * memClass / 10;
bitmapCache = new LruCache<String, Bitmap>(cacheSize) {
  @Override
  protected int sizeOf(String key, Bitmap value) {
    return value.getHeight() * value.getRowBytes();
 }
};

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

4 голосов
/ 25 апреля 2011

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

Например, с помощью простого счетчика общего байта: просто добавьте или переместите любой элемент, используемый в верхней части списка, добавьте его размер к счетчику, если он новый.Удалите снизу, если общее количество байтов превысит ваш предел эмпирического правила, тем самым уменьшив ваш счетчик.Может быть, класс LinkedHashMap полезен для этого: его можно использовать как кеш, как HashMap, но у него тоже порядок, как у списка.

2 голосов
/ 23 февраля 2011

Проблема в том, что SoftReferences полезны для выделений, выполняемых в пространстве кучи Java, но изображения размещаются изначально, поэтому этот тип кэша не будет работать на Android.

1 голос
/ 16 октября 2013

вы не можете динамически увеличивать размер кучи.

вы можете запросить использование большего количества, используя android: largeHeap = "true" в манифесте, но вы можете не получить больше размера кучи, чем обычно,поскольку это всего лишь запрос.

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

вот несколько постов, которые я сделал по этому поводу:

и вот библиотека, которую я сделал для нее:

0 голосов
/ 08 января 2011

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

Вы хотите проверить, как это делается на полках: см. Строку 82 в http://code.google.com/p/shelves/source/browse/trunk/Shelves/src/org/curiouscreature/android/shelves/util/ImageUtilities.java?r=26

...