Подтвердить что ты не робот

Android: как увеличить размер кучи во время выполнения?

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

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

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

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

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

4b9b3361

Ответ 1

Вместо увеличения размера кучи вы можете сделать что-то лучше. Как вы сказали, вы поддерживаете кэш в своем приложении, которое реализовано с помощью 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 и загрузит в нее новое изображение.

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

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

вот несколько сообщений, которые я сделал об этом:

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

Ответ 5

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

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