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

Как вы программно обнаруживаете размер кучи приложения, ansible для Android-приложения?

Я слышал, что есть функция, которая делает это в более поздних версиях SDK. В любом случае, я ищу решение, которое работает на 1,5 и выше.

9 Solutions collect form web for “Определить размер кучи приложения в Android”

Есть два способа подумать о вашей фразе «ansible размер кучи приложения»:

  1. Сколько кучи может использовать мое приложение до того, как будет запущена жесткая ошибка? А также

  2. Сколько кучи должно использовать мое приложение, учитывая ограничения версии ОС Android и аппаратного обеспечения устройства пользователя?

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

Для пункта 1 выше: maxMemory()

который может быть вызван (например, в onCreate() вашего основного действия) следующим образом:

 Runtime rt = Runtime.getRuntime(); long maxMemory = rt.maxMemory(); Log.v("onCreate", "maxMemory:" + Long.toString(maxMemory)); 

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

Для пункта 2 выше: getMemoryClass()

который может быть вызван следующим образом:

 ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); int memoryClass = am.getMemoryClass(); Log.v("onCreate", "memoryClass:" + Integer.toString(memoryClass)); 

Этот метод говорит вам примерно о том, сколько мегабайт кучи, которое должно использовать ваше приложение, если оно хочет быть должным образом уважительным в отношении ограничений настоящего устройства и прав других приложений на запуск без повторного onStop() в onStop() / onResume() поскольку они грубо вымываются из памяти, а ваше приложение для слонов принимает ванну в джакузи Android.

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

Для биржевой версии Android maxMemory() обычно возвращает примерно maxMemory() же мегабайт, как указано в getMemoryClass() (т. getMemoryClass() Примерно в миллион раз больше последнего значения).

Единственная ситуация (о которой я знаю), для которой эти два метода могут расходиться, – это внедренное устройство, на котором установлена ​​версия Android, такая как CyanogenMod, которая позволяет пользователю вручную выбирать, насколько большой размер кучи должен быть разрешен для каждого приложения. Например, в CM эта опция появляется в разделе «Настройки CyanogenMod» / «Производительность» / «Размер кучи VM».

ПРИМЕЧАНИЕ. УКАЗЫВАЙТЕ, ЧТО УСТАНОВКА ЭТОТ ЗНАЧЕНИЕ МОЖЕТ СООТВЕТСТВОВАТЬ ВАШЕЙ СИСТЕМЕ, ОСОБЕННО, если вы выберете меньшее значение, чем обычно для вашего устройства.

Вот мои результаты теста, показывающие значения, возвращаемые maxMemory() и getMemoryClass() для четырех различных устройств, работающих под управлением CyanogenMod, с использованием двух разных (вручную заданных) значений кучи для каждого:

  • G1:
    • С размером кучи VM установлено значение 16 МБ:
      • maxMemory: 16777216
      • getMemoryClass: 16
    • С размером кучи VM установлено значение 24 МБ:
      • maxMemory: 25165824
      • getMemoryClass: 16
  • Мото-дроид:
    • С размером кучи VM установлено значение 24 МБ:
      • maxMemory: 25165824
      • getMemoryClass: 24
    • С размером кучи VM установлено значение 16 МБ:
      • maxMemory: 16777216
      • getMemoryClass: 24
  • Nexus One:
    • Если размер кучи VM установлен равным 32 МБ:
      • maxMemory: 33554432
      • getMemoryClass: 32
    • С размером кучи VM установлено значение 24 МБ:
      • maxMemory: 25165824
      • getMemoryClass: 32
  • Viewsonic GTab:
    • Если размер кучи VM установлен равным 32:
      • maxMemory: 33554432
      • getMemoryClass: 32
    • Если размер кучи VM установлен равным 64:
      • maxMemory: 67108864
      • getMemoryClass: 32

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

Для этого устройства приведены следующие результаты:

  • Novo7
    • maxMemory: 62914560
    • getMemoryClass: 60

Также (за Кишоре в комментарии ниже):

  • HTC One X
    • maxMemory: 67108864
    • getMemoryClass: 64

И (за комментарий akauppi):

  • Samsung Galaxy Core Plus
    • maxMemory: (Не указано в комментарии)
    • getMemoryClass: 48
    • largeMemoryClass: 128

За комментарий от cmcromance:

  • Galaxy S3 (Jelly Bean) большая куча
    • maxMemory: 268435456
    • getMemoryClass: 64

И (за комментарии tencent):

  • LG Nexus 5 (4.4.3) нормальный
    • maxMemory: 201326592
    • getMemoryClass: 192
  • LG Nexus 5 (4.4.3) большая куча
    • maxMemory: 536870912
    • getMemoryClass: 192
  • Galaxy Nexus (4.3) нормальный
    • maxMemory: 100663296
    • getMemoryClass: 96
  • Galaxy Nexus (4.3) большая куча
    • maxMemory: 268435456
    • getMemoryClass: 96
  • Galaxy S4 Play Store Edition (4.4.2) обычный
    • maxMemory: 201326592
    • getMemoryClass: 192
  • Galaxy S4 Play Store Edition (4.4.2) большая куча
    • maxMemory: 536870912
    • getMemoryClass: 192

Другие устройства

  • Huawei Nexus 6P (6.0.1) нормальный
    • maxMemory: 201326592
    • getMemoryClass: 192

Я не тестировал эти два метода, используя специальный вариант манифеста android: largeHeap = “true”, ansible с Honeycomb, но благодаря cmcromance и tencent у нас есть некоторые значения sampleHeap образца, как сообщалось выше.

Мое ожидание (которое, по-видимому, поддерживается большими числами выше), будет заключаться в том, что этот параметр будет иметь эффект, аналогичный настройке кучи вручную с помощью корневой ОС, т. maxMemory() Он повысит значение maxMemory() , оставив getMemoryClass() в одиночестве. Существует еще один метод getLargeMemoryClass (), который указывает, сколько памяти допустимо для приложения, используя параметр largeHeap. Документация для getLargeMemoryClass () гласит: «большинству приложений не нужен этот объем памяти, а должен остаться с пределом getMemoryClass ()».

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

Обратите внимание, что class памяти, по-видимому, не должен быть кратным 8 МБ.

Из вышеизложенного getMemoryClass() что результат getMemoryClass() неизменен для данной конфигурации устройства / ОС, а значение maxMemory () изменяется, когда куча устанавливается пользователем по-разному.

Мой собственный практический опыт заключается в том, что на G1 (который имеет class памяти 16), если я вручную выберем 24 МБ в качестве размера кучи, я могу работать без ошибок даже тогда, когда моему использованию памяти разрешено дрейфовать до 20 МБ (предположительно это могло до 24 МБ, хотя я этого не пробовал). Но другие подобные приложения большого размера могут быть покраснели из памяти в результате свинства моего собственного приложения. И, наоборот, мое приложение может быть сброшено из памяти, если эти другие приложения с высоким уровнем обслуживания будут выведены на передний план пользователем.

Таким образом, вы не можете переместить объем памяти, указанный maxMemory() . И вы должны стараться оставаться в пределах, указанных getMemoryClass() . Один из способов сделать это, если все остальное не удастся, может заключаться в ограничении функциональности для таких устройств таким образом, чтобы сохранить память.

И, наконец, если вы планируете пойти по количеству мегабайт , указанных в getMemoryClass() , мой совет будет работать долго и упорно на сохранения и восстановления состояния вашего приложения, так что опыт пользователя является практически непрерывным , если onStop() / onResume() .

В моем случае, по причине производительности, я ограничиваю свое приложение устройствами, работающими под управлением 2.2 и выше, а это означает, что почти все устройства, на которых работает мое приложение, будут иметь memoryClass 24 или выше. Таким образом, я могу разработать, чтобы занять до 20 Мбайт кучи и чувствовать себя уверенно, что мое приложение будет хорошо работать с другими приложениями, которые пользователь может запускать одновременно.

Но всегда будет несколько корневых пользователей, которые загрузили 2.2 или более позднюю версию Android на более старое устройство (например, G1). Когда вы сталкиваетесь с такой конфигурацией, в идеале, вы должны избавиться от использования вашей памяти, даже если maxMemory() сообщает вам, что вы можете пойти намного выше, чем 16MB, что getMemoryClass() сообщает вам, что вы должны getMemoryClass() таргетинг. И если вы не можете надежно убедиться, что ваше приложение будет жить в рамках этого бюджета, то, по крайней мере, убедитесь, что onStop() / onResume() работает без проблем.

getMemoryClass() , как указано Diane Hackborn (hackbod) выше, доступно только на уровне API 5 (Android 2.0), и поэтому, как она советует, вы можете предположить, что физическое оборудование любого устройства, использующего более раннюю версию ОС предназначена для оптимальной поддержки приложений, занимающих кучу не более 16 МБ.

Напротив, maxMemory() , согласно документации, полностью возвращается к уровню API 1. maxMemory() в версии до 2.0, вероятно, вернет значение 16 МБ, но я вижу, что в моем (много позже) версии CyanogenMod пользователь может выбрать значение кучи как 12 МБ, что, по-видимому, приведет к более низкому пределу кучи, и поэтому я предлагаю вам продолжить тестирование значения maxMemory() даже для версий ОС до 2,0. Возможно, вам даже придется отказаться от запуска в маловероятном случае, когда это значение будет установлено даже ниже 16 МБ, если вам нужно указать больше, чем maxMemory() .

Официальный API :

Это было введено в версии 2.0, где появились более крупные устройства памяти. Вы можете предположить, что устройства, работающие с предыдущими версиями ОС, используют исходный class памяти (16).

Debug.getNativeHeapSize() будет делать трюк. Это было там с 1.0.

Класс Debug имеет множество отличных методов отслеживания распределений и других проблем производительности. Кроме того, если вам нужно обнаружить ситуацию с низкой памятью, проверьте Activity.onLowMemory() .

Вот как вы это делаете:

Получение максимального размера кучи, который приложение может использовать:

 Runtime runtime = Runtime.getRuntime(); long maxMemory=runtime.maxMemory(); 

Как узнать, сколько кучи используется в настоящее время в вашем приложении:

 long usedMemory=runtime.totalMemory() - runtime.freeMemory(); 

Как узнать, сколько из кучи может использовать ваше приложение (доступная память):

 long availableMemory=maxMemory-usedMemory; 

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

 String formattedMemorySize=Formatter.formatShortFileSize(context,memorySize); 

Это возвращает максимальный размер кучи в байтах:

 Runtime.getRuntime().maxMemory() 

Я использовал ActivityManager.getMemoryClass (), но на CyanogenMod 7 (я не тестировал его в другом месте) он возвращает неправильное значение, если пользователь задает размер кучи вручную.

Asus Nexus 7 (2013) 32Gig: getMemoryClass () = 192 maxMemory () = 201326592

Я допустил ошибку в прототипировании своей игры на Nexus 7, а затем обнаружил, что у нее почти не осталось памяти на общем 4.04 таблетке моей жены (memoryclass 48, maxmemory 50331648)

Мне нужно будет перестроить мой проект, чтобы загрузить меньше ресурсов, когда я определяю, что class памяти низкий.
Есть ли способ в Java увидеть текущий размер кучи? (Я вижу это ясно в logCat при отладке, но мне бы хотелось увидеть его в коде для адаптации, например, если currentheap> (maxmemory / 2) разгружает высококачественные растровые изображения, загружая низкое качество

Некоторые операции выполняются быстрее, чем диспетчер пространства кучи java. Операции задержки в течение некоторого времени могут освобождать пространство памяти. Вы можете использовать этот метод, чтобы избежать ошибки размера кучи:

 waitForGarbageCollector(new Runnable() { @Override public void run() { // Your operations. } }); /** * Measure used memory and give garbage collector time to free up some * space. * * @param callback Callback operations to be done when memory is free. */ public static void waitForGarbageCollector(final Runnable callback) { Runtime runtime; long maxMemory; long usedMemory; double availableMemoryPercentage = 1.0; final double MIN_AVAILABLE_MEMORY_PERCENTAGE = 0.1; final int DELAY_TIME = 5 * 1000; runtime = Runtime.getRuntime(); maxMemory = runtime.maxMemory(); usedMemory = runtime.totalMemory() - runtime.freeMemory(); availableMemoryPercentage = 1 - (double) usedMemory / maxMemory; if (availableMemoryPercentage < MIN_AVAILABLE_MEMORY_PERCENTAGE) { try { Thread.sleep(DELAY_TIME); } catch (InterruptedException e) { e.printStackTrace(); } waitForGarbageCollector( callback); } else { // Memory resources are availavle, go to next operation: callback.run(); } } 

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

 Runtime rt = Runtime.getRuntime(); rt.maxMemory() 

значение – b

 ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); am.getMemoryClass() 

значение – МБ

  • В Java, каков наилучший способ определить размер объекта?
  • Как найти утечку памяти Java
  • В чем разница между оператором присваивания и конструктором копирования?
  • Создайте функцию обертки для malloc и освободите ее на C
  • Заказ локального распределения переменных в стеке
  • Какие страtagsи и инструменты полезны для обнаружения утечек памяти в .NET?
  • Циркулярные ссылки Причина утечки памяти?
  • Размер байт в памяти - Java
  • Создание утечки памяти с помощью Java
  • Общая страtagsя для устранения утечки памяти Java?
  • java.lang.OutOfMemoryError: размер растрового изображения превышает бюджет VM - Android
  • Interesting Posts

    Можете ли вы клонировать более крупный диск на меньший диск (используемое пространство подходит для меньшего размера)

    Существует ли ExecutorService, который использует текущий stream?

    Установите Windows 8 Upgrade на новый SSD?

    objective союзов в C и C ++

    Выберите строку с самой последней датой для каждого пользователя

    Заполнение любых пустых ячеек значением выше

    Как вы можете разрешить mutt шифровать письма в папке отправленной почты?

    Преобразование строки временной метки unix в удобочитаемую дату

    Maven: Что такое pluginManagement?

    Изменение местоположений, показанных на стороне открытой панели

    Ручки против потоков против процессов

    Как восстановить Windows 7 с помощью теневых копий?

    Является ли stream статического конструктора C # безопасным?

    Повторите последнюю команду, соответствующую «двум словам» zsh

    Обработка тайм-аута сеанса в вызовах ajax

    Давайте будем гением компьютера.