Jestem dość ciekawy tego pytania dotyczącego zarządzania pamięcią w systemie operacyjnym Android, więc liczę na dość szczegółową odpowiedź na ten temat.
Co chciałbym wiedzieć:
- Jaka jest maksymalna ilość pamięci (w megabajtach / jako procent całkowitej pamięci RAM), z której może korzystać aplikacja na Androida (która nie jest aplikacją systemową)?
- Czy są jakieś różnice między wersjami Androida ?
- Czy są jakieś różnice dotyczące producenta urządzenia?
I co najważniejsze:
- Co jest brane pod uwagę / od czego to zależy, jeśli chodzi o system określający, ile pamięci RAM aplikacja może używać w czasie wykonywania (zakładając, że maksymalna pamięć na aplikację nie jest liczbą statyczną)?
Co słyszałem do tej pory (do 2013 roku):
- Wczesne urządzenia z Androidem miały limit 16 MB na aplikację
- Później ten limit został zwiększony do 24 MB lub 32 MB
Co mnie bardzo zaciekawia:
Obie te limity są bardzo niskie.
Niedawno pobrałem Menedżera zadań Androida, aby sprawdzić pamięć RAM moich urządzeń. Zauważyłem, że niektóre aplikacje używają około 40-50 megabajtów pamięci RAM, czyli oczywiście więcej niż wspomniane maksymalne użycie pamięci RAM, powiedzmy 32 MB. Jak więc Android ustala, ile pamięci RAM może używać aplikacja? Jak to możliwe, że aplikacje przekraczają ten limit?
Co więcej, zauważyłem, że niektóre moje aplikacje ulegają awarii (zabite przez system?) Z OutOfMemoryException podczas używania około 30-40 megabajtów. Z drugiej strony mam aplikacje działające na moim telefonie, które używają 100 MB i więcej po pewnym czasie (prawdopodobnie z powodu wycieków pamięci), które nie ulegają awarii ani nie zostają zabite. Więc oczywiście zależy to również od samej aplikacji, jeśli chodzi o określenie, ile pamięci RAM można zaoszczędzić. Jak to jest możliwe? (Testy przeprowadziłem z HTC One S z 768 MB RAM)
Zastrzeżenie: NIE jestem w żaden sposób powiązany z aplikacją Android Task Manager.
źródło
Jest koniec 2018 roku, więc wszystko się zmieniło.
Po pierwsze: uruchom aplikację i otwórz zakładkę Android Profiler w Android Studio. Zobaczysz, ile pamięci zużywa, będziesz zaskoczony, ale może przydzielić dużo pamięci RAM.
Również tutaj jest wielki artykuł w oficjalnych docs szczegółowe instrukcje na temat korzystania z pamięci Profiler, które może dać ci dogłębnie swojego zarządzania pamięcią.
Ale w większości przypadków wystarczy Ci zwykły Android Profiler.
Zwykle aplikacja zaczyna się od alokacji 50 MB pamięci RAM, ale natychmiast przeskakuje do 90 MB po rozpoczęciu ładowania niektórych zdjęć do pamięci. Po otwarciu Aktywności za pomocą ViewPagera z fabrycznie załadowanymi zdjęciami (po 3,5 MB każdy) możesz łatwo uzyskać 190 MB w kilka sekund.
Ale to nie znaczy, że masz problemy z zarządzaniem pamięcią.
Najlepsza rada, jaką mogę dać, to postępować zgodnie ze wskazówkami i najlepszymi praktykami, używać najlepszych bibliotek do ładowania obrazów (Glide, Picasso) i wszystko będzie dobrze.
Ale jeśli chcesz coś dostosować i naprawdę potrzebujesz wiedzieć, ile pamięci możesz przydzielić ręcznie, możesz uzyskać całkowitą wolną pamięć i obliczyć z góry określoną część (w%). W moim przypadku potrzebowałem buforować odszyfrowane zdjęcia w pamięci, więc nie muszę ich odszyfrowywać za każdym razem, gdy użytkownik przesuwa się po liście.
W tym celu możesz skorzystać z gotowej do użycia klasy LruCache . Jest to klasa pamięci podręcznej, która automatycznie śledzi ilość pamięci przydzielonej przez obiekty (lub liczbę instancji) i usuwa najstarsze, aby zachować najnowsze według historii użycia. Oto świetny samouczek, jak go używać.
W moim przypadku utworzyłem 2 instancje pamięci podręcznych: dla kciuków i załączników. Ustawiono je jako statyczne dzięki dostępowi singleton, dzięki czemu są dostępne globalnie w całej aplikacji.
klasa pamięci podręcznej:
Oto jak obliczam dostępną wolną pamięć RAM i ile mogę z niej ugryźć:
I tak używam go w adapterach, aby uzyskać buforowany obraz:
i jak ustawiłem go w pamięci podręcznej w wątku w tle (zwykłe AsyncTask):
Moja aplikacja jest ukierunkowana na API 19+, więc urządzenia nie są stare, a te części dostępnej pamięci RAM są wystarczająco dobre dla pamięci podręcznej w moim przypadku (1% i 3%).
Ciekawostka: Android nie ma żadnych interfejsów API ani innych hacków, aby uzyskać ilość pamięci przydzielonej do Twojej aplikacji, jest obliczana na bieżąco na podstawie różnych czynników.
PS Używam statycznego pola klasy do przechowywania pamięci podręcznej, ale zgodnie z najnowszymi wytycznymi Androida zaleca się użycie do tego celu komponentu architektury ViewModel .
źródło
Limity pamięci na aplikację są tutaj w zależności od rozmiaru ekranu i wersji Androida: https://drive.google.com/file/d/0B7Vx1OvzrLa3Y0R0X1BZbUpicGc/view?usp=sharing
Źródło: Android Compatibility Downloads http://source.android.com/compatibility/downloads.html ; Dokument definicji zgodności (CDD), sekcja dotycząca zgodności maszyn wirtualnych lub zgodności środowiska wykonawczego
źródło