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

125

Я пишу приложение для Android, использующее несколько 3D-моделей. Такая модель с текстурами может занимать много памяти. Я узнал, что производитель устанавливает ограничение на размер кучи, который может использовать приложение. Например, мой планшет Samsung Galaxy Tab 8.9 P7310 может занимать 64 МБ памяти.

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

cooxie
источник

Ответы:

210

Вы можете использовать android: largeHeap = "true", чтобы запросить больший размер кучи, но это не будет работать ни на каких устройствах до Honeycomb. На устройствах до 2.3 вы можете использовать класс VMRuntime, но это не будет работать на Gingerbread и выше.

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

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

Рагхав Суд
источник
NDK выглядит интересно. Могу ли я использовать его в сочетании с моим кодом, уже написанным с помощью SDK?
Cooxie
3
Это полностью зависит от того, какой у вас код. Я не специалист по NDK и знаю только основы. Я бы порекомендовал вам задать этот вопрос вместе с описанием вашего кода в группе Google android-ndk или опубликовать новый вопрос о SO, специфичном для этого, с тегом android-ndk.
Raghav Sood
Интересно, не можем ли мы «просто» использовать Unity3D как более конкретный ответ на вопрос («использует несколько 3D-моделей») ... Не удалось быстро найти какие-либо четкие доказательства того, действительно ли Unity использует NDK.
cregox
3
largeHeap=trueFTW
Луис Артола
2
разработчики android api действительно смешные, они вроде хочешь еще кучи? Хорошо, запросите это, это только для тех, кому это нужно ... тем временем каждый разработчик добавляет его в первую очередь, когда приложение поступает в производство :)
AndroidLover
110

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

Приложения, работающие на уровне API 11+, могут иметь android:largeHeap="true"в <application>элементе манифеста запросить размер кучи больше обычного, и getLargeMemoryClass()on ActivityManagerсообщит вам, насколько велика эта куча. Тем не мение:

  1. Это работает только на уровне API 11+ (например, Honeycomb и выше).

  2. Нет гарантии, насколько большой будет большая куча.

  3. Пользователь будет воспринимать ваш запрос большой кучи, потому что он вынудит другие его приложения из ОЗУ завершать процессы других приложений, чтобы освободить системную ОЗУ для использования вашей большой кучей

  4. Из-за № 3 и того факта, что я ожидаю, что этим android:largeHeapбудут злоупотреблять, поддержка этого может быть прекращена в будущем, или пользователь может быть предупрежден об этом во время установки (например, вам нужно будет запросить специальное разрешение для этого )

  5. В настоящее время эта функция немного документирована.

CommonsWare
источник
@CommonsWare, если наличие largeHeap недоступно, как я могу удалить ранее загруженные объекты (например, изображения)?
Jeongbebs
@MiguelRivera: Для изображений, в идеале вы перерабатывают их память (см inBitmapна BitmapOptions). Кроме того, удалите все ссылки на них, и в конечном итоге они будут собраны мусором.
CommonsWare
и какое решение вы предлагаете?
Геннадий Рябкин
@zest: я не понимаю, о чем вы, извините.
CommonsWare
2
@Eftekhari: Не напрямую, для вашего приложения. Наличие большего количества вещей может привести к тому, что вы потратите больше времени ЦП на эти вещи, но детали там будут зависеть от того, что вы делаете с памятью, и не связаны напрямую с запросом android:largeHeap. Однако запрос большой кучи может нанести вред пользователю в целом, вынуждая другие процессы приложения завершаться раньше, чем это потребовалось бы в противном случае.
CommonsWare
22

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

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

Кроме того, вы можете использовать native memory (NDK & JNI), чтобы фактически обойти ограничение размера кучи.

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

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

разработчик Android
источник
@ для каждого приложения лимит кучи на уровне Java отличается от собственного? т.е. пример на s5 devcie 128mb java heap limit и native может взять еще 128 mb?
NitZRobotKoder
Размер кучи постоянен для каждого приложения (размер зависит от оборудования и ПЗУ) и должен быть одинаковым для всех. Собственная память - это настоящая память устройства, но она, конечно, тоже ограничена, так как часть ее используется ОС.
разработчик Android
Я имел в виду, если мое приложение использует, скажем, собственный .so + java android Platform + java POJO logic + JavaScript. У Android разный размер кучи на каждом уровне?
NitZRobotKoder
@NitZRobotKoder Нет. Размер кучи предназначен для мира Java / Kotlin, где вы можете получить исключение OOM, если используете слишком много. В остальном это родная память.
разработчик Android
6

Используйте второй процесс. Объявить в AndroidManifestновом Serviceс

android:process=":second"

Обмен между первым и вторым процессом закончился BroadcastReceiver

Юра Шинкарев
источник
5

Это можно сделать двумя способами в зависимости от вашей ОС Android.

  1. Вы можете использовать android:largeHeap="true"тег приложения в манифесте Android, чтобы запросить больший размер кучи, но это не будет работать ни на каких устройствах, предшествующих Honeycomb.
  2. На устройствах до 2.3 вы можете использовать класс VMRuntime , но это не будет работать на Gingerbread и выше. См. Ниже, как это сделать.
VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE);

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

Ссылка: http://dwij.co.in/increase-heap-size-of-android-application

Веб-разработчик в Пуне
источник
4
Таким образом, очевидно, что у <2.3 есть способ, а у> 2.3 есть способ, но 2.3 не работает!
Майкл
3

Насколько я помню, вы могли использовать VMRuntimeclass в ранних версиях Android, но теперь больше не можете.

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

разъем
источник
0

Увеличение Java Heap несправедливо пожирает дефицит мобильных ресурсов. Иногда достаточно просто дождаться сборки сборщика мусора, а затем возобновить работу после того, как пространство кучи уменьшится. Тогда используйте этот статический метод .

Зон
источник