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

Два вопроса о максимальных размерах кучи и доступной памяти в android

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

Итак, мой первый вопрос: каковы типичные размеры Max Heap на устройствах Android? Я проверил распределение памяти на одном телефоне, который смог использовать кучу более 40 Мб, а другой выдал ошибки OutOfMemory в 20 мб. Каковы самые низкие, которые широко используются, и каковы самые высокие показатели на обычных устройствах? Есть ли стандартный или средний?

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

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

Например, если устройство разрешало максимальную кучу 24 МБ, и приложение приближалось к этому пределу при распределении, то оно могло обнаруживать и масштабировать назад. Однако, если устройство сможет комфортно обрабатывать больше, оно сможет воспользоваться преимуществами того, что доступно.

Спасибо

4b9b3361

Ответ 1

У ранних устройств была кепка для каждого приложения размером 16 МБ. Позже устройства увеличили это до 24 МБ. Будущие устройства, скорее всего, будут доступны еще больше.

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

Изменить: Дополнительные размышления...

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

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

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

Куча Dalvik находится в активной разработке (см., например, заметки на Android 2.3 "Gingerbread", в которой представлен параллельный GC), поэтому, надеюсь, эти проблемы будут рассмотрены в будущей версии.

Изменить: Обновить...

Механизм "внешнего распределения" ушел в 4.0 (Ice Cream Sandwich). Данные пикселов для битмапов теперь хранятся в куче Dalvik, избегая более ранних раздражений.

Последние устройства (например, Nexus 4) закрывают размер кучи при 96 МБ или более.

Общий смысл пределов памяти приложения может быть получен как "класс памяти", от ActivityManager.getMemoryClass(). Более конкретное значение может быть получено из функции java.lang.Runtime maxMemory().

Ответ 2

Ниже приведены "обычные" (см. ниже) размеры кучи для некоторых конкретных устройств:

  • G1:16MB
  • Мото-дроид: 24 МБ
  • Nexus One: 32 МБ
  • Viewsonic GTab: 32MB
  • Ново7 Паладин: 60 МБ

Я говорю "нормальный", потому что некоторые версии Android (например, CyanogenMod) позволят пользователю вручную настроить ограничение кучи. Результат может быть больше или меньше, чем "нормальные" значения.

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

Определить размер кучи приложений в Android

Чтобы определить, что такое текущее использование кучи, вы можете попробовать использовать метод totalMemory() класса Runtime. Тем не менее, я читал отчеты о том, что в разных версиях/реализациях ОС Android могут быть разные политики в отношении того, подсчитывается ли основная память (из которой выделена резервная память для растровых изображений) против максимума кучи или нет. И, начиная с версии 3.0, собственная память непосредственно берется из собственной кучи приложения.

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

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

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

Существуют также методы программирования на Java, которые позволяют объявлять определенную память, подлежащую возврату сборщиком мусора по требованию, даже если она имеет существующие "мягкие" (а не жесткие) ссылки. Если у вас есть данные, которые вы хотели бы сохранить в памяти, но которые могут быть повторно загружены из энергонезависимого хранилища, если это необходимо (то есть кэш), то вы можете подумать об использовании мягких ссылок, чтобы такая память автоматически освобождалась, когда ваше приложение начинает натыкаться на верхние пределы вашей кучи. См. Эту страницу для информации о мягких ссылках на Android:

http://developer.android.com/reference/java/lang/ref/SoftReference.html