2014-10-29 13 views
8

Obecnie mam pustą aplikację LibGDX, która ma nic nie ma. Nie renderuje niczego, ani niczego nie aktualizuje. To jest po prostu pusty Screen. Kiedy wdrażam aplikację na Androida, wita mnie przerażająca konsumpcja pamięci. Korzystanie DDMS utworzyć następujący zrzut stosu, gdy aplikacja jest uruchomiona na moim urządzeniu:Android graficzne ogromne zużycie pamięci sterty? - LibGDX

enter image description here

Najistotniejszą użycie pamięci jest 13,163 MB 1-bajtowy tablicy alokacji. Czy to nie połowa kupy ?!

Sprawdziłem alokacje i zobaczył, że nic nie wskazywał przydzielenia tej wielkości:

enter image description here

Teraz za pomocą Eclipse MAT I analizować zrzutu sterty:

enter image description here

Tak wysokie wykorzystanie pamięci nadal pochodzi z tablic bajtowych []. Analizując byte [] Rozdział dalej wymyślić to:

enter image description here

Teraz widzę ogromny byte [] przydziały pochodzą z android grafiki. Nawet niczego nie rysuję! Czy jest jakiś sposób, aby uniknąć sytuacji, w której część z Androidem w tej aplikacji zajmuje połowę sterty. To powoduje, że nadmierne zbieranie śmieci ma miejsce, gdy coś się dzieje, czy jest to normalne i po prostu muszę sobie z tym poradzić?

Uwaga: Używam tego na Samsung Galaxy S4 z libgdx wersji 1.4 (lub cokolwiek jest najnowsza wersja)

UPDATE: ja nie odkrył, że przydział 14-13MB bajt tablicy jest normalne dla aplikacji ale wciąż mam problem. Mój rozmiar sterty jest za mały. Jeśli grafika z Androidem zajmuje połowę mojej sterty, mam mało miejsca na nic przydatnego, a śmieciarz szaleje. Na innej aplikacji stworzyłem ze starszą wersją libgdx (niezaprzeczalnie słabiej zakodowaną aplikacją), a wielkość sterty to 73 Mb. Jak mogę zwiększyć rozmiar sterty? Domyślam się, że 73 Mb jest dość duże i jak widać większość z nich nie jest używana. Oto statystyki kupie starszej aplikacji: enter image description here

+1

Czy próbowałeś przydzielić trochę śmieci, aby spróbować przekroczyć rozmiar sterty pierwszej aplikacji, która ma mały rozmiar sterty? Jeśli nie, zrób to. Czy automatycznie zwiększa swój rozmiar sterty, gdy jest to zrobione? –

Odpowiedz

6

Po wersji Androida 2.3 nie można zrobić nic o rozmiarze sterty innym niż przy użyciu atrybutu android: largeHeap.

Istnieją dwa sposoby, aby oszukać jeśli chcesz wielka kupa nie ważne co:

  1. Korzystanie z native api przydzielić pamięci: nie jest dobrym pomysłem, gdyż zwiększa złożoność i jeśli nie jesteś planowanie robienia rzeczy w natywnym kodzie,
  2. Przydzielanie niepotrzebnie dużego obiektu przed wykonaniem, aby uzyskać pożądaną przestrzeń sterty: Chociaż da to dość miejsca na sterty tylko jeden raz, nie ma gwarancji, że rozmiar sterty pozostanie taki sam .

Jednak początkowy rozmiar sterty nie stanowi problemu, jeśli zostanie zmieniony w razie potrzeby. Moja opinia na temat zarządzania pamięcią w cyklu życia gry jest trochę inna niż te dwie rzeczy wymienione powyżej i co prawdopodobnie robisz.

Dla poziomu, etapu itp. Nie należy przydzielać pamięci dokładnie w tym momencie, kiedy jej potrzebujesz. Spowoduje to nie tylko zacinanie się przy przydzielaniu pamięci, ale także jąkanie z powodu możliwych operacji wejścia/wyjścia. Wszystko, jak dźwięki, grafika, czcionki itp. Powinno być przygotowane przed poziomem. Właśnie dlatego wiele gier ma ekran "ładowania". Powinieneś przygotować wszystko, co możesz zrobić przed rozpoczęciem gry.

Dla małego etapu, robienie tego jest OK-ale nadal nie jest dobre-. Ponieważ wszystko stanie się skomplikowane, obniży to wydajność. Wiele gier (takich jak gry sportowe, gry wyścigowe itp.) Wykonuje alokację przed rozpoczęciem gry. Inni robią to tak bardzo, jak tylko mogą. Niektóre gry z otwartym światem (takie jak GTA) nie ładują wszystkich obiektów mapy na mapie, ale mają zasięg remisu, więc rysują podczas poruszania się po mapie i usuwają najdalsze obiekty z pamięci, gdy pamięć nie ma więcej miejsca .

[Powodem, dla którego Twoja aplikacja ze starszą wersją LibGDX ma większy rozmiar sterty, jest prawdopodobnie przydział, który spowodował wzrost wielkości sterty i zwalnianie, które uwolniło część sterty, aby uzyskać dobre 30% wykorzystania.]

+0

Dziękujemy, że to bardzo pomocne! – grimrader22

+0

Nie ma za co! –

1

Można przypisać tę wartość atrybutu w Android manifeście:

android:largeHeap="true"

uwaga, będzie to działać tylko na Androidzie 3.0+

+0

Po dodaniu tego do manifestu, rozmiar sterty pozostaje na poziomie 26,465Mb, nie zbliża się do 73,855 MB drugiej aplikacji. Niedawno odkryłem, że stertę zmieni się tylko, jeśli ta wartość jest prawdziwa, jeśli zabraknie jej pamięci, której nie posiadam. Ścinanie aplikacji nadal często występuje z powodu GC_FOR_ALLOC, którego spodziewam się zmniejszyć poprzez zwiększenie wielkości sterty? Na drugiej aplikacji wspomniałem, że użyto tylko 30%, co znaczy, że GC_FOR_ALLOC nie zdarzałoby się zbyt często. W pierwszym zastosowaniu użyto 60%. – grimrader22

+0

Czy istnieje sposób na zwiększenie rozmiaru sterty, mimo że technicznie tego nie potrzebuję? – grimrader22

+0

Obawiam się, że nie mam wtedy pojęcia. Jedyny sposób, jaki znam, to powyższe. – Bowersbros

1

prawo- Kliknij przydzielony obiekt, wybierz "trace to GC root", "z wyłączeniem słabych odniesień"

+0

Co to pomogłoby mi rozwiązać? – grimrader22

+0

można znaleźć sposób, w jaki przydzielony obiekt jest połączony z innymi obiektami i znaleźć w ten sposób wyciek pamięci. https://developer.android.com/tools/debugging/debugging-memory.html Używając narzędzia Eclipse Memory Analyzer Tool – konmik

+0

Niedawno oflagowałem tę odpowiedź jako nie odpowiedź, ale flaga została odrzucona. Wygląda na to, że jest prawidłową treścią, ale brakuje mu kontekstu wspaniałej odpowiedzi. Może chcesz go rozszerzyć dla jasności? – brandonscript

Powiązane problemy