Jak zwiększyć rozmiar sterty aplikacji na Androida?

125

Piszę aplikację na Androida, która wykorzystuje kilka modeli 3D. Taki model z teksturami może zajmować dużo pamięci. Dowiedziałem się, że producent ustala limit rozmiaru sterty, z którego może korzystać aplikacja. Na przykład mój tablet Samsung Galaxy Tab 8.9 P7310 może zająć 64 MB pamięci.

Czy istnieje sposób na zwiększenie tego rozmiaru pamięci, z którego może korzystać aplikacja?

Cooxie
źródło

Odpowiedzi:

210

Możesz użyć android: largeHeap = "true", aby zażądać większego rozmiaru sterty, ale nie będzie to działać na żadnym urządzeniu starszym niż Honeycomb. Na urządzeniach w wersji starszej niż 2.3 możesz używać klasy VMRuntime, ale nie będzie to działać na Gingerbread i nowszych wersjach.

Jedynym sposobem na uzyskanie tak dużego limitu, jak to tylko możliwe, jest wykonywanie zadań intensywnie wykorzystujących pamięć za pośrednictwem NDK, ponieważ NDK nie nakłada ograniczeń pamięci, tak jak SDK.

Alternatywnie, możesz wczytać tylko część modelu, która jest aktualnie widoczna, a resztę w razie potrzeby, jednocześnie usuwając nieużywane części z pamięci. Jednak w zależności od aplikacji może to być niemożliwe.

Raghav Sood
źródło
NDK wygląda interesująco. Czy mogę go używać w połączeniu z moim kodem już napisanym za pomocą SDK?
Cooxie
3
To zależy całkowicie od posiadanego kodu. Nie jestem ekspertem w NDK i znam tylko podstawy. Poleciłbym zadać to pytanie wraz z opisem swojego kodu w grupie Android-ndk Google lub zadać nowe pytanie na temat SO dotyczące tego z tagiem android-ndk.
Raghav Sood
Zastanawiam się, czy nie możemy „po prostu” użyć Unity3D jako bardziej szczegółowej odpowiedzi na pytanie („używa kilku modeli 3D”)… Nie udało się szybko znaleźć żadnych wyraźnych dowodów na to, czy jedność używa NDK.
cregox
3
largeHeap=trueFTW
Luis Artola
2
twórcy Android API są naprawdę zabawni, są tak, jakbyś chciał więcej Heap? Ok, poproś o to, to tylko dla tych, którzy tego potrzebują ... tymczasem każdy programista dodaje to jako pierwszą rzecz, którą dodaje, gdy aplikacja trafi do produkcji :)
AndroidLover
110

Czy istnieje sposób na zwiększenie tego rozmiaru pamięci, z którego może korzystać aplikacja?

Aplikacje działające na API Level 11+ może mieć android:largeHeap="true"na <application>element manifest zwrócić większą niż normalna wielkość sterty, a getLargeMemoryClass()on ActivityManagerpowie Ci, jak duża jest to kupa. Jednak:

  1. Działa to tylko na poziomie API 11+ (tj. Plaster miodu i nie tylko)

  2. Nie ma gwarancji, jak duża będzie duża sterta

  3. Użytkownik zauważy twoje żądanie dużej sterty, ponieważ wymusi to na innych aplikacjach z pamięci RAM, które zakończy procesy innych aplikacji, aby zwolnić systemową pamięć RAM do wykorzystania przez dużą stertę

  4. Ze względu na # 3 i fakt, że spodziewam się, że android:largeHeapbędzie nadużywany, wsparcie dla tego może zostać w przyszłości porzucone lub użytkownik może zostać o tym ostrzeżony w czasie instalacji (np. Będziesz musiał poprosić o specjalne pozwolenie na to )

  5. Obecnie ta funkcja jest słabo udokumentowana

CommonsWare
źródło
@CommonsWare, jeśli opcja LargeHeap nie jest dostępna, jak mogę usunąć wcześniej załadowane obiekty (takie jak obrazy)?
Jeongbebs
@MiguelRivera: W przypadku obrazów najlepiej jest ponownie wykorzystać ich pamięć (patrz inBitmapdalej BitmapOptions). Poza tym usuń wszystkie odniesienia do nich, a ostatecznie zostaną zebrane jako śmieci.
CommonsWare
i jaką decyzję proponujesz?
Gennadiy Ryabkin
@zest: Nie wiem, o czym mówisz, przepraszam.
CommonsWare,
2
@Eftekhari: Nie bezpośrednio, dla Twojej aplikacji. Posiadanie większej ilości rzeczy może spowodować, że poświęcisz więcej czasu procesora na przeglądanie tych rzeczy, ale szczegóły będą zależeć od tego, co robisz z pamięcią i nie są bezpośrednio związane z żądaniem android:largeHeap. Jednak żądanie dużej sterty może ogólnie zaszkodzić użytkownikowi, zmuszając inne procesy aplikacji do zakończenia wcześniejszego niż byłoby to potrzebne w innym przypadku.
CommonsWare
22

nie można dynamicznie zwiększać rozmiaru sterty.

możesz poprosić o użycie więcej, używając android:largeHeap="true"w manifeście.

możesz również użyć native memory (NDK & JNI), więc faktycznie pomijasz ograniczenie rozmiaru sterty.

oto kilka postów, które napisałem na ten temat:

a oto biblioteka, którą dla niego stworzyłem:

programista Androida
źródło
@ per app czy limit sterty na poziomie java i natywny jest inny? np. na s5 devcie 128mb limit sterty java i natywny może zająć kolejne128 MB?
NitZRobotKoder,
Rozmiar sterty jest stały dla każdej aplikacji (rozmiar zależy od sprzętu i pamięci ROM) i powinien być taki sam dla wszystkich. Pamięć natywna jest rzeczywistą pamięcią urządzenia, ale oczywiście jest również ograniczona, ponieważ część z niej jest używana przez system operacyjny.
programista Androida
Miałem na myśli, jeśli moja aplikacja używa, powiedzmy, natywnej platformy .so + java Android Platform + java POJO logic + JavaScript. Czy Android ma inny rozmiar sterty na każdym poziomie?
NitZRobotKoder,
@NitZRobotKoder Nie. Rozmiar sterty dotyczy świata Java / Kotlin, w którym można uzyskać wyjątek OOM, jeśli używasz zbyt dużo. Reszta to pamięć natywna.
programista Androida
6

Użyj drugiego procesu. Zadeklaruj jako AndroidManifestnowy Servicez

android:process=":second"

Wymiana między pierwszym a drugim procesem zakończona BroadcastReceiver

Yura Shinkarev
źródło
5

Można to zrobić na dwa sposoby w zależności od systemu operacyjnego Android.

  1. Możesz użyć android:largeHeap="true"w tagu aplikacji manifestu systemu Android, aby zażądać większego rozmiaru sterty, ale nie będzie to działać na żadnych urządzeniach z wcześniejszą wersją plastra miodu.
  2. Na urządzeniach w wersji starszej niż 2.3 możesz używać klasy VMRuntime , ale nie będzie to działać na Gingerbread i nowszych. Zobacz poniżej, jak to zrobić.
VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE);

Przed ustawieniem HeapSize upewnij się, że wprowadziłeś odpowiedni rozmiar, który nie wpłynie na inne funkcje aplikacji lub systemu operacyjnego. Przed ustawieniami sprawdź, jaki rozmiar zajmuje Twoja aplikacja, a następnie ustaw rozmiar, aby spełnić swoje zadanie. Nie używaj tak dużo pamięci, w przeciwnym razie inne aplikacje mogą mieć wpływ.

Źródła: http://dwij.co.in/increase-heap-size-of-android-application

Web Developer w Pune
źródło
4
Najwyraźniej <2.3 ma sposób, a> 2.3 ma sposób, ale 2.3 jest schrzaniony!
Michael
3

Z tego, co pamiętam, mogłeś używać VMRuntimeklasy we wczesnych wersjach Androida, ale teraz już nie możesz.

Nie sądzę jednak, aby pozwolić deweloperowi wybrać rozmiar sterty w środowisku mobilnym, można uznać za tak bezpieczne. Myślę, że łatwiej jest znaleźć sposób na zmodyfikowanie rozmiaru sterty w określonym urządzeniu (nie po stronie programowania), próbując zmodyfikować go z poziomu samej aplikacji.

Jacek
źródło
0

Zwiększanie ilości Java Heap niesprawiedliwie zjada niedobór zasobów mobilnych. Czasami wystarczy poczekać na garbage collector, a następnie wznowić działanie po zmniejszeniu miejsca na sterty. Następnie użyj tej statycznej metody .

Zon
źródło