Як збільшити розмір купи програми для Android?


125

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

Чи є спосіб збільшити цей об'єм пам'яті, який може використовувати програма?

Відповіді:


210

Ви можете використовувати android: largeHeap = "true", щоб запитувати більший розмір купи, але це не працюватиме на будь-яких попередніх пристроях соти. На пристроях до 2.3 ви можете використовувати клас VMRuntime, але це не буде працювати на Пряників та вище.

Єдиний спосіб отримати максимально можливий ліміт - це виконувати завдання, що займають пам'ять, через NDK, оскільки NDK не встановлює обмеження пам'яті, як SDK.

Крім того, ви можете завантажувати лише ту частину моделі, яку зараз переглядаєте, та завантажувати решту, як вам потрібно, видаляючи із пам'яті невикористані деталі. Однак це може бути неможливим, залежно від вашої програми.


NDK виглядає цікаво. Чи можу я використовувати його в поєднанні з кодом, уже написаним SDK?
cooxie

3
Це повністю залежить від того, який код у вас є. Я не фахівець з NDK, і знаю лише основи. Я рекомендую вам задати це запитання разом з описом свого коду в групі Google android-ndk або опублікувати нове запитання щодо ТАК, характерного для цього, з тегом android-ndk.
Рагхав Суд

Цікаво, чи не можемо ми просто "використовувати" Unity3D як більш конкретний відповідь на питання ("використовує кілька 3D-моделей") ... Не вдалося швидко знайти чітких доказів того, чи використовує єдність NDK.
Крегокс

3
largeHeap=trueFTW
Луїс Артола

2
розробники андроїд api справді смішні, вони схожі на те, що ви хочете більше Heap? Добре запитайте, це лише для тих, хто цього потребує ... тим часом кожен розробник додає це як перше, що потрібно додати, коли додаток з'явиться :)
AndroidLover

110

Чи є спосіб збільшити цей об'єм пам'яті, який може використовувати програма?

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

  1. Це працює лише на рівні API 11+ (тобто стільникові та більше)

  2. Немає гарантій, якою буде велика купа

  3. Користувач сприйме ваш великий запит, оскільки він змусить їх інші додатки з оперативної пам’яті припинити процеси інших додатків звільнити системну оперативну пам’ять для використання великою купу

  4. Через №3 і те, що я очікую, що android:largeHeapзловживатимуть, підтримка цього в майбутньому може бути відмовлена ​​або користувач може попередити про це під час встановлення (наприклад, вам потрібно буде попросити спеціальний дозвіл на це )

  5. В даний час ця особливість легко зафіксована


@CommonsУважте, якщо велика допомога недоступна, як я можу видалити раніше завантажені об'єкти (наприклад, зображення)?
Jeongbebs

@MiguelRivera: Для зображень, в ідеалі ви переробляють їх пам'ять (див inBitmapна BitmapOptions). Крім цього, видаліть усі посилання на них, і з часом вони отримають сміття.
CommonsWare

і яке рішення ви пропонуєте?
Геннадій Рябкін

@zest: Я не знаю, на що ви звертаєтесь, вибачте.
CommonsWare

2
@Eftekhari: безпосередньо для вашого додатка. Наявність більшої кількості матеріалів може призвести до того, що ви витратите більше часу на процесор, переглядаючи цей матеріал, але деталі там залежать від того, що ви робите з пам'яттю, і це не пов'язано безпосередньо з запитом android:largeHeap. Однак запит на велику купу може завдати шкоди користувачеві загалом, змусивши інші прикладні процеси припинятися раніше, ніж це було б потрібно інакше.
CommonsWare

22

не можна динамічно збільшувати розмір купи.

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

також ви можете використовувати native memory (NDK & JNI), так що ви фактично обходите обмеження розміру купи.

ось кілька публікацій, які я зробив про це:

і ось бібліотека, яку я створив для цього:


@ на додаток чи обмежує купу на рівні Java, а рідне - це інше? наприклад приклад на s5 devcie 128mb java heap limit та native може взяти ще128 mb?
NitZRobotKoder

Розмір купи є постійним для кожного додатка (розмір залежить від апаратного забезпечення та рома) і має бути однаковим для всіх. Нативна пам’ять - справжня частина пристрою, але вона, звичайно, також обмежена, оскільки частина її використовується ОС.
андроїд розробник

Я мав на увазі, якщо в моєму додатку використовується скажімо рідний .so + java android Platform + java POJO логіка + JavaScript. Чи має андроїд різний розмір купи на кожному рівні?
NitZRobotKoder


@NitZRobotKoder Ні. Розмір купи призначений для світу Java / Kotlin, де ви можете отримати виняток OOM, якщо використовуєте занадто багато. В іншому - це рідна пам’ять.
андроїд розробник

6

Використовуйте другий процес. Оголосити AndroidManifestнове Serviceс

android:process=":second"

Обмін між першим і другим процесом закінчений BroadcastReceiver


5

Це можна зробити двома способами відповідно до вашої ОС Android.

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

Перш ніж встановити HeapSize, переконайтеся, що ви ввели відповідний розмір, який не впливатиме на інші додатки чи ОС. Перед налаштуваннями просто перевірте, який розмір займає ваша програма, а потім встановіть розмір лише для виконання вашої роботи. Не використовуйте стільки пам'яті, інакше це може вплинути на інші програми.

Довідка: http://dwij.co.in/increase-heap-size-of-android-application


4
Отже, мабуть, <2.3 має спосіб, а> 2.3 - спосіб, але 2.3 - це гвинт!
Майкл

3

Як я пам’ятаю, ви могли використовувати VMRuntimeклас у ранніх версіях Android, але тепер ви вже не можете.

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


0

Збільшення Java Heap несправедливо з'їдає дефіцит мобільних підйомів. Іноді достатньо просто дочекатися збирання сміття, а потім відновити свої дії після зменшення місця купи. Потім використовуйте цей статичний метод .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.