Jakie są zalety ustawienia wartości true dla parametru largeHeap?

122

Mam aplikację z prawie 50 klasami, które ustawiam android:largeHeap="true", jak widać poniżej. Czy to dobra praktyka?

<application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="Mall"
        android:largeHeap="true"
        android:logo="@drawable/logo_for_up"
        android:screenOrientation="portrait"
        android:theme="@style/AppTheme" >
</application>

Uprzejmie zasugeruj zalety i wady korzystania z niego.

Mam problemy z pamięcią, dlatego zadaję to pytanie.

Intsab Haider
źródło
jeśli potrzebujesz dużej pamięci do swojej aplikacji, takiej jak gry, modele 3D itp.
styczeń
47
50 zajęć to niewiele.
Chris Hayes,
jeśli korzystasz z jakiejś usługi lub jakiejkolwiek innej aplikacji w swojej aplikacji, która zużywa pamięć, twoja aplikacja będzie miała problem z pamięcią, taki jak kamera jest najczęstszym problemem na twarzy programisty podczas korzystania z aplikacji lub jeśli masz dużo zmiennych, które zużywają pamięć lub statyczne zmienna może być również tego przyczyną.
Aditi
4
Liczba zajęć nie jest ważna. To, co zwykle zajmuje dużo pamięci, to mapy bitowe. Zobacz „ Ładowanie zmniejszonej wersji do pamięci ”.
ToolmakerSteve

Odpowiedzi:

116

O wiele za późno na imprezę tutaj, ale i tak zaoferuję moje 0,02 $.
Nie jest dobrym pomysłem używanie android:largeHeap="true" tutaj fragmentu z Google, który to wyjaśnia,

Jednak możliwość zażądania dużej sterty jest przeznaczona tylko dla niewielkiego zestawu aplikacji, które mogą uzasadniać potrzebę zużywania większej ilości pamięci RAM (na przykład duża aplikacja do edycji zdjęć). Nigdy nie żądaj dużej sterty tylko dlatego, że zabrakło Ci pamięci i potrzebujesz szybkiej naprawy - powinieneś jej używać tylko wtedy, gdy wiesz dokładnie, gdzie jest przydzielana cała twoja pamięć i dlaczego należy ją zachować. Jednak nawet jeśli masz pewność, że Twoja aplikacja może uzasadnić dużą stertę, powinieneś unikać żądania jej w jak największym stopniu. Korzystanie z dodatkowej pamięci będzie w coraz większym stopniu niekorzystne dla ogólnego doświadczenia użytkownika, ponieważ czyszczenie pamięci zajmie więcej czasu, a wydajność systemu może być wolniejsza podczas przełączania zadań lub wykonywania innych typowych operacji.

tutaj jest pełny link do dokumentacji https://developer.android.com/training/articles/memory.html

AKTUALIZACJA

Po dokładnej pracy z out of memory errorspowiedziałbym, że dodanie tego do manifestu, aby uniknąć problemu oom, nie jest grzechem, również jak @Milad wskazuje poniżej, nie wpływa to na normalne działanie aplikacji

AKTUALIZACJA 2

Oto kilka wskazówek, które zajmują sięout of memory errors

1) Skorzystaj z tych wywołań zwrotnych, które daje Android onLowMemory, onTrimMemory(int) i wyczyść pamięć podręczną obrazu, takiego jak (picasso, glide, fresco ...), możesz przeczytać więcej o nich tutaj i tutaj
2) skompresuj swoje pliki (obrazy, pdf)
3) przeczytaj o jak wydajniej obsługiwać mapę bitową w tym miejscu
4) Regularnie używaj kłaczków przed wypchnięciami produkcyjnymi, aby kod był elegancki i nie zajmował dużo miejsca

Mightian
źródło
1
Dlaczego mówisz „nie ma to wpływu na normalne działanie aplikacji”? Ta odpowiedź omawia niektóre konsekwencje. Gdzie indziej widziałem jeszcze gorsze czasy zmierzone dla GC largeHeap w niektórych aplikacjach.
ToolmakerSteve
59

Myślę, że jest to bardzo skuteczne pytanie i pozwolę sobie dodać kilka szczegółów na temat zalet i wad korzystania z tej opcji.

Co dostałeś :

  • Oczywiście otrzymujesz większy stos, co oznacza zmniejszenie ryzyka OutOfMemoryError.

Co tracisz:

  • Możesz zgubić niektóre ramy, co może spowodować widoczne zaczepienie . Większy stos wydłuża czas zbierania elementów bezużytecznych. Ponieważ odśmiecacz musi w zasadzie przejść przez cały twój aktywny zestaw obiektów. Zwykle czas przerwy w usuwaniu elementów bezużytecznych wynosi około 5 ms i możesz pomyśleć, że kilka milisekund to nic wielkiego. Ale liczy się każda milisekunda. Urządzenie z Androidem musi aktualizować swój ekran co 16 ms, a dłuższy czas GC może przesunąć czas przetwarzania ramki ponad 16 milisekundową barierę, co może spowodować widoczne zacięcie.

  • Również przełączanie aplikacji będzie wolniejsze . System Android może zabijać procesy w pamięci podręcznej LRU, zaczynając od procesu najmniej ostatnio używanego, ale także biorąc pod uwagę, które procesy zużywają najwięcej pamięci. Jeśli więc używasz większej sterty, Twój proces prawdopodobnie zostanie zabity, gdy będzie działał w tle, co oznacza, że ​​może to zająć więcej czasu, gdy użytkownicy będą chcieli przełączać się z innych aplikacji na Twoją. Również inne procesy działające w tle będą bardziej prawdopodobne, że zostaną wyrzucone, gdy twój proces jest na pierwszym planie, ponieważ twoja aplikacja wymaga większej pamięci. Oznacza to, że przejście z aplikacji do innych aplikacji również trwa dłużej.

Wniosek:

W largeHeapmiarę możliwości unikaj korzystania z opcji. Może to kosztować trudny do zauważenia spadek wydajności i złe wrażenia użytkownika.

김준호
źródło
17

Mam aplikację z prawie 50 zajęciami

Nie sądzę, żeby to stanowiło duży problem. Powodem, dla którego masz błąd outOfMemory, jest zwykle ładowanie zbyt dużej liczby obrazów w Twojej aplikacji lub coś w tym rodzaju. Jeśli nie jesteś zadowolony z używania dużej sterty, musisz znaleźć sposób na optymalizację wykorzystania pamięci.

Możesz także użyć bibliotek ładowania obrazów, takich jak Picasso , UIL lub Glide . Wszystkie mają funkcję buforowania obrazu w pamięci i / lub na dysku.

Milad Faridnia
źródło
1
do ładowania obrazu generalnie polecam picaso lub uniwersalny program ładujący obraz
Mightian
5
Glide jest lepszy i nieco bardziej zoptymalizowany niż Picasso
Damien Praca,
1
@DamienPraca Nie sądzę, przynajmniej jeśli poprawnie używasz tagów (setTag (), pauseTag (), resumeTag ()) w Picassie.
Ruslan Berozov
15

Właściwie android: largeHeap to narzędzie do zwiększania ilości pamięci przydzielonej do aplikacji.

Nie ma jasnej definicji potrzeby używania tej flagi. Jeśli potrzebujesz więcej pamięci - Android zapewnia narzędzie do jej zwiększenia. Ale konieczność używania, definiujesz siebie.

Sergey Shustikov
źródło
4
tak, istnieje jasna definicja, odnieś ten link developer.android.com/training/articles/memory.html
Mightian
2
@war_Hero - może ten artykuł zmienił treść? Nie ma w nim wzmianki o largeHeap.
ToolmakerSteve
7

Jeśli musisz używać (i zachować) dużą ilość pamięci, to tak, możesz i powinieneś używać android:largeHeap="true". Ale jeśli go używasz, powinieneś być przygotowany na opróżnienie aplikacji z pamięci, gdy inne aplikacje są na pierwszym planie.

Przez „bądź przygotowany” rozumiem, że powinieneś projektować pod kątem takiego prawdopodobieństwa, aby twoje metody onStop()i onResume()metody były napisane tak wydajnie, jak to tylko możliwe, przy jednoczesnym zapewnieniu, że wszystkie stosowne stany są zapisywane i przywracane w sposób, który przedstawia bezproblemowy wygląd użytkownikowi.

Istnieją trzy metody, które odnoszą się do tego parametru: maxMemory(), getMemoryClass(), i getLargeMemoryClass().

W przypadku większości urządzeń domyślnie maxMemory()będzie reprezentować podobną wartość getMemoryClass(), chociaż ta ostatnia jest wyrażona w megabajtach, podczas gdy ta pierwsza jest wyrażona w bajtach.

Gdy użyjesz tego largeHeapparametru, maxMemory()zostanie zwiększony do wyższego poziomu specyficznego dla urządzenia, podczas gdy getMemoryClass()pozostanie taki sam.

getMemoryClass()nie ogranicza rozmiaru sterty, ale informuje o ilości sterty, której należy użyć, jeśli chcesz, aby aplikacja działała wygodnie i kompatybilnie w granicach określonego urządzenia, na którym używasz.

maxMemory(), Przeciwnie, ma ograniczyć rozmiar sterty, a więc zrobić uzyskać dostęp do dodatkowych sterty poprzez zwiększenie jej wartości, a largeHeapnie wzrost tej wartości. Jednak zwiększona ilość sterty jest nadal ograniczona, a ten limit będzie zależny od urządzenia, co oznacza, że ​​ilość sterty dostępnej dla Twojej aplikacji będzie się różnić w zależności od zasobów urządzenia, na którym działa aplikacja. Dlatego używanie largeHeapnie jest zaproszeniem dla aplikacji do porzucenia wszelkiej ostrożności i przejścia przez bufet typu „wszystko, co możesz”.

Twoja aplikacja może dokładnie określić, ile pamięci byłoby dostępne na określonym urządzeniu za pomocą largeHeapparametru, wywołując metodę getLargeMemoryClass(). Zwracana wartość jest w megabajtach.

Ten wcześniejszy post zawiera omówienie largeHeapparametru, a także szereg przykładów tego, jakie ilości sterty są udostępniane z użyciem i bez jego użycia na kilku konkretnych urządzeniach z Androidem:

Wykryj rozmiar sterty aplikacji w systemie Android

Nie wdrożyłem żadnych własnych aplikacji z tym parametrem ustawionym na true. Jednak w jednej z moich aplikacji mam kod wymagający dużej ilości pamięci do kompilowania zestawu parametrów związanych z optymalizacją, który działa tylko podczas programowania. largeHeapParametr dodaję tylko podczas programowania, aby uniknąć błędów braku pamięci podczas uruchamiania tego kodu. Ale usuwam parametr (i kod) przed wdrożeniem aplikacji.

Carl
źródło
1
„porzuć wszelką ostrożność i przejdź przez bufet all-you-can-eat” 😂
Joshua Pinter
4

Czy procesy aplikacji powinny być tworzone z dużą stertą Dalvik. Dotyczy to wszystkich procesów utworzonych dla aplikacji. Dotyczy tylko pierwszej aplikacji załadowanej do procesu; jeśli używasz wspólnego identyfikatora użytkownika, aby umożliwić wielu aplikacjom korzystanie z procesu, wszystkie muszą konsekwentnie korzystać z tej opcji, w przeciwnym razie wyniki będą nieprzewidywalne.

Większość aplikacji nie powinna tego potrzebować i zamiast tego powinny skupić się na zmniejszeniu ogólnego zużycia pamięci w celu poprawy wydajności. Włączenie tego również nie gwarantuje stałego wzrostu dostępnej pamięci, ponieważ niektóre urządzenia są ograniczone przez ich całkowitą dostępną pamięć.

Murali Ganesan
źródło