Jestem całkiem nowy w rozwoju Androida i nie mogę zrozumieć wyjątku Java Out of Memory. Wiem, że oznacza to, że moja aplikacja przekroczyła budżet maszyny wirtualnej, ale po wielokrotnym przeszukiwaniu go nadal nie wydaje mi się, aby rozumieć tę koncepcję. Obawiam się, że moja aplikacja zużywa zbyt dużo pamięci, ponieważ mam sześć przycisków na ekranie z dwiema mapami bitowymi dla każdego selektora, których rozmiar wynosi około 20 kb zgodnie z zakładką właściwości. Na moim zrootowanym G2x ustawiłem budżet VM na 12MB, zrestartowałem mój telefon i uruchomiłem moją aplikację bez żadnych problemów. Rozplątuję rysunki na każdym z nich onDestroy() i podpowiedź na GC, żeby tu również biegać. Po pewnym czasie korzystania z aplikacji w emulatorze klikam "Przyczyna GC" na ekranie DDMS, a wyniki są następujące: ID = 1, rozmiar sterty 6.133 MB, przydzielony 2.895 MB, bezpłatny 3.238 MB,% używany 47,20, # obiekty 52.623.Rozumienie Rozmiarów Androida Rozumienie Rozmiarów
To tutaj nie rozumiem, co się dzieje, mój emulator jest ustawiony na 24MB VM. Gdzie jest ta liczba? Rzeczywisty problem, który mam, polega na tym, że jeśli ustawię emulator na 16MB VM, moja aplikacja ulega awarii podczas drugiej aktywności z wyjątkiem braku pamięci. Jak to się stało, że nie zawiesił się na moim telefonie z VM ustawionym na 12 MB lub na moim starym telefonie HTC Magic z 12 MB pamięci VM? Myślicie też, że moja aplikacja zajmuje zbyt dużo pamięci? Nie mam pojęcia, czy te numery DDMS są dobre, czy nie. Dziękuję za Twój czas.
Jeśli chodzi o mój kod, mam każdy obraz określony w układach XML, nie robię z nim nic programistycznie, poza dodawaniem do nich odbiorców. Znalazłem ten fragment kodu tu i dodałem go do każdej działalności, że mam ...
@Override
protected void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.myRootLayout));
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
inaczej zrobić to dodać onClickListeners do przycisków, które mają PNG tła. Chciałbym nauczyć się programowo definiować tła przycisków, ale muszę mieć funkcje selektora, jak na fokusie, na prasie, nie skupiony, ale wciśnięty itp., Aby zmienić tło przycisków zgodnie z interakcją użytkownika. Sprawdziłem dokumenty na ten temat, ale wydaje się to przytłaczające, dlatego pomyślałem, że zacznę tutaj od podstaw zarządzania Heapsami i pracuję nad określeniem selektorów w kodzie. To może nie mieć sensu, ale czy istnieje "zdrowa" ilość alokacji pamięci, którą aplikacja może przydzielić, nie zbliżając się do wyjątku braku pamięci? Na przykład, jeśli aplikacja ma przydzielone 6 MB, powinno być w porządku, ale 8 MB będzie ją przesyłać, czy są jakieś ograniczenia w alokacji pamięci? Jeszcze raz dziękuję Alexowi Lockwoodowi za odpowiedź. Przeczytam i ponownie ją przeczytam, dopóki to nie będzie dla mnie sensowne.
+1, bardzo pouczająca odpowiedź! –
Dziękuję bardzo! Wiele się z tego nauczyłem. Dodaję trochę informacji na końcu pytania. –
Komentarz do rozdzielczości "20 kb każdy brzmi dobrze" - AFAIK, nie ma znaczenia rozmiar * pliku * (który będzie mniejszy dla obrazów, które kompresują lepiej), ważne są * WYMIARY *; w pamięci, dla pełnego koloru, zajmie 4B na piksel, prawda? Dlatego ważne jest, aby zmienić rozmiar obrazu po załadowaniu go [dokumenty android - ładowanie wersji skalowanej do pamięci], w oparciu o rzeczywisty wymagany rozmiar dla bieżącego urządzenia. – ToolmakerSteve