Как вы программно определяете размер кучи приложения, доступного для приложения Android?
Я слышал, что есть функция, которая делает это в более поздних версиях SDK. В любом случае, я ищу решение, которое работает на 1,5 и выше.
android
memory
heap
heap-memory
hpique
источник
источник
Ответы:
Есть два способа подумать о вашей фразе «доступный размер кучи приложения»:
Сколько кучи может использовать мое приложение до появления серьезной ошибки? И
Сколько кучи должно использовать мое приложение, учитывая ограничения версии ОС Android и аппаратного обеспечения устройства пользователя?
Существует другой метод определения каждого из вышеперечисленных.
Для пункта 1 выше:
maxMemory()
который может быть вызван (например, в
onCreate()
методе вашей основной деятельности ) следующим образом:Этот метод сообщает, сколько всего байтов кучи разрешено использовать вашему приложению .
Для пункта 2 выше:
getMemoryClass()
который может быть вызван следующим образом:
Этот метод сообщает вам приблизительно, сколько мегабайт кучи должно использовать ваше приложение, если оно хочет должным образом уважать ограничения существующего устройства и права других приложений на запуск без повторного принудительного ввода в
onStop()
/onResume()
цикл поскольку они грубо не хватает памяти, пока ваше приложение для слонов принимает ванну в джакузи Android.Насколько мне известно, это различие не совсем задокументировано, но я проверил эту гипотезу на пяти различных устройствах Android (см. Ниже) и, к моему собственному удовлетворению, подтвердил, что это правильная интерпретация.
Для стандартной версии Android
maxMemory()
обычно возвращается примерно столько же мегабайт, сколько указано вgetMemoryClass()
(т. Е. Примерно в миллион раз больше последнего значения).Единственная ситуация (о которой я знаю), для которой эти два метода могут расходиться, - это устройство на руте, работающее под управлением версии Android, такой как CyanogenMod, которая позволяет пользователю вручную выбирать какой размер кучи должен быть разрешен для каждого приложения. Например, в CM этот параметр отображается в «Настройках CyanogenMod» / «Производительность» / «Размер кучи виртуальной машины».
ПРИМЕЧАНИЕ: ВНИМАНИЕ, ЧТО УСТАНОВКА ЭТОГО ЗНАЧЕНИЯ ВРУЧНУЮ МОЖЕТ ПОПРОБУТЬ ВАШУ СИСТЕМУ, ОСОБЕННО, если вы выберете меньшее значение, чем обычно для вашего устройства.
Вот результаты моего теста, показывающие значения, возвращаемые
maxMemory()
иgetMemoryClass()
для четырех разных устройств, работающих под управлением CyanogenMod, с использованием двух разных (устанавливаемых вручную) значений кучи для каждого:В дополнение к вышесказанному, я протестировал планшет Novo7 Paladin с Ice Cream Sandwich. По сути, это была стандартная версия ICS, за исключением того, что я проверил планшет через простой процесс, который не заменяет всю ОС, и, в частности, не предоставляет интерфейс, который позволял бы настраивать размер кучи вручную.
Для этого устройства вот результаты:
Также (за Кишора в комментарии ниже):
И (согласно комментарию Акауппи):
За комментарий от cmcromance:
И (комментарии tencent):
Другие устройства
Я не тестировал эти два метода, используя специальный параметр android: largeHeap = "true", доступный со времен Honeycomb, но благодаря cmcromance и tencent у нас есть некоторые примерные значения largeHeap, как сообщалось выше.
Мои ожидания (которые , как представляется, поддерживаются числами largeHeap выше) будут то , что этот вариант будет иметь эффект , подобную установку кучи вручную через корневые ОСА - то есть, это повысит ценность
maxMemory()
, оставляяgetMemoryClass()
в покое. Есть еще один метод, getLargeMemoryClass (), который указывает, сколько памяти разрешено для приложения, использующего параметр largeHeap. Документация для getLargeMemoryClass () гласит: «большинству приложений не требуется такой объем памяти, и вместо этого они должны оставаться с ограничением getMemoryClass ()».Если я правильно угадал, то использование этой опции будет иметь те же преимущества (и опасности), что и использование пространства, выделенного пользователем, который поднял кучу через рутированную ОС (т. Е. Если ваше приложение использует дополнительную память, он, вероятно, не будет играть так же хорошо с другими приложениями, которые одновременно запускает пользователь).
Обратите внимание, что класс памяти, очевидно, не должен быть кратным 8 МБ.
Из вышесказанного видно, что
getMemoryClass()
результат для данной конфигурации устройства / ОС остается неизменным, в то время как значение maxMemory () изменяется, когда куча задается пользователем по-разному.Мой собственный практический опыт заключается в том, что на G1 (который имеет класс памяти 16), если я вручную выберу 24 МБ в качестве размера кучи, я могу работать без ошибок, даже если использование моей памяти может дойти до 20 МБ (предположительно, это может доходит до 24 МБ, хотя я не пробовал это). Но другие приложения такого же большого размера могут быть выгружены из памяти из-за скудности моего собственного приложения. И, наоборот, мое приложение может быть выгружено из памяти, если пользователь выводит эти другие приложения с высоким уровнем обслуживания.
Таким образом, вы не можете использовать объем памяти, указанный в
maxMemory()
. И вы должны стараться не выходить за пределы, указанные вgetMemoryClass()
. Одним из способов сделать это, если ничего не помогает, может быть ограничение функциональности таких устройств таким образом, чтобы сохранить память.И наконец, если вы планируете превысить указанное в мегабайтах количество
getMemoryClass()
, я бы посоветовал долго и усердно работать над сохранением и восстановлением состояния вашего приложения, чтобы пользовательский интерфейс практически не прерывался при возникновении циклаonStop()
/onResume()
.В моем случае, из соображений производительности, я ограничиваю свое приложение устройствами, работающими под управлением 2.2 и выше, а это означает, что почти все устройства, на которых запущено мое приложение, будут иметь класс памяти 24 или выше. Поэтому я могу спроектировать так, чтобы занимать до 20 МБ кучи, и чувствую себя довольно уверенно, что мое приложение будет хорошо работать с другими приложениями, которые пользователь может одновременно запускать.
Но всегда будет несколько пользователей с правами root, которые загрузили версию Android 2.2 или выше на старое устройство (например, G1). Когда вы сталкиваетесь с такой конфигурацией, в идеале вам следует сократить использование памяти, даже если
maxMemory()
он говорит вам, что вы можете пойти намного выше, чем 16 МБ, которыйgetMemoryClass()
говорит вам, что вы должны нацеливаться. И если вы не можете надежно гарантировать, что ваше приложение будет жить в рамках этого бюджета, то по крайней мере убедитесь, чтоonStop()
/onResume()
работает без проблем.getMemoryClass()
как указано выше Дианой Хакборн (hackbod), она доступна только для уровня API 5 (Android 2.0), и поэтому, как она советует, можно предположить, что физическое оборудование любого устройства, работающего под управлением более ранней версии ОС, разработано для оптимальной поддержки приложений, занимающих пространство кучи не более 16 МБ.В отличие от этого
maxMemory()
, в соответствии с документацией, доступен весь путь обратно к уровню API 1.maxMemory()
на предварительной версии 2.0, вероятно , возвращает значение 16MB, но я делать видим , что в моих (много позже) CyanogenMod версий пользователей Можно выбрать значение кучи до 12 МБ, что, вероятно, приведет к более низкому пределу кучи, и поэтому я бы посоветовал вам продолжить тестировать этоmaxMemory()
значение даже для версий ОС до 2.0. Возможно, вам даже придется отказаться от запуска в маловероятном случае, если это значение установлено даже ниже 16 МБ, если вам нужно иметь больше, чемmaxMemory()
указано, разрешено.источник
Официальный API это:
источник
Debug.getNativeHeapSize()
Я подумаю. Это было там с 1.0, хотя.В
Debug
классе есть много отличных методов для отслеживания распределений и других проблем производительности. Кроме того, если вам нужно обнаружить нехватку памяти, проверьтеActivity.onLowMemory()
.источник
Вот как вы это делаете:
Получение максимального размера кучи, который может использовать приложение:
Как узнать, сколько кучи использует ваше приложение:
Получение того, сколько кучи может теперь использовать ваше приложение (доступная память):
И, чтобы красиво отформатировать каждый из них, вы можете использовать:
источник
Это возвращает максимальный размер кучи в байтах:
Я использовал ActivityManager.getMemoryClass (), но в CyanogenMod 7 (я не проверял его в других местах) он возвращает неправильное значение, если пользователь устанавливает размер кучи вручную.
источник
getMemoryClass
видимому, подразумевает, что число может не совпадать с доступным размером кучи для вашего виртуального компьютера, а поскольку документ дляgetNativeHeapSize
... молчалив, я действительно думаю, чтоRuntime.getRuntime().maxMemory()
это лучший ответ.Некоторые операции выполняются быстрее, чем менеджер пространства кучи Java. Задержка операций на некоторое время может освободить место в памяти. Вы можете использовать этот метод, чтобы избежать ошибки размера кучи:
источник
AvailableMemoryPercentage
в соответствии с формулой: сколько памяти устройства в настоящее время свободно.MIN_AVAILABLE_MEMORY_PERCENTAGE
ваш пользовательский параметр, порог, при котором вы начинаете ждать, пока сборщик мусора выполнит свою работу.Asus Nexus 7 (2013) 32Gig: getMemoryClass () = 192 maxMemory () = 201326592
Я сделал ошибку, прототипировав свою игру на Nexus 7, а затем обнаружил, что почти сразу же не хватило памяти на обычном планшете моей жены 4.04 (memoryclass 48, maxmemory 50331648)
Мне нужно будет реструктурировать свой проект, чтобы загружать меньше ресурсов, когда я определяю, что класс памяти мал.
Есть ли способ в Java, чтобы увидеть текущий размер кучи? (Я вижу это ясно в logCat при отладке, но мне бы хотелось, чтобы это можно было увидеть в коде для адаптации, например, если currentheap> (maxmemory / 2) выгружает высококачественные растровые изображения загружает низкое качество
источник
Вы имеете в виду программно или просто во время разработки и отладки? Если последнее, вы можете увидеть эту информацию с точки зрения DDMS в Eclipse. Когда ваш эмулятор (возможно, даже физический телефон, который подключен) работает, он выведет список активных процессов в окне слева. Вы можете выбрать его, и есть возможность отслеживать распределение кучи.
источник
значение b
значение МБ
источник
rt
? Где это заявлено?