Два вопроса о максимальных размерах кучи и доступной памяти в Android - PullRequest
22 голосов
/ 04 декабря 2010

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

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

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

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

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

Спасибо

Ответы [ 2 ]

8 голосов
/ 07 декабря 2010

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

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

Редактировать: Дополнительные размышления ...

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

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

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

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

Редактировать: Обновить ...

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

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

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

5 голосов
/ 25 февраля 2012

Вот «нормальные» (см. Ниже) размеры кучи для некоторых конкретных устройств:

  • G1: 16 МБ
  • Moto Droid: 24 МБ
  • Nexus One: 32 МБ
  • Viewsonic GTab: 32 МБ
  • Novo7 Паладин: 60 МБ

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

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

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

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

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

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

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

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

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

...