2015-12-14 14 views
7

Mam trudności ze znalezieniem możliwego wycieku pamięci. Mam aktywność, która wykonuje ciężką pracę w tle.W jaki sposób Android Studio uruchamia Garbage Collector i jak to działa?

Po wykonaniu niektórych zadań aplikacja zużywa zbyt dużo pamięci. Wygląda na to, że nie jest prawidłowo czyszczony.

To jest aktywny w stanie domyślnym:

enter image description here

Gdybym uruchomić zadanie, które robi aktywny, coraz więcej pamięci jest przydzielona.

aktywny po jakimś pracy: enter image description here

Na początku myślałem, że to musi być problem pamięci, powodują GC nie może prawidłowo zwolnić pamięć. O ile mi wiadomo, GC może zwolnić pamięć, jeśli nie ma odniesienia do Przedmiotów. Czy to jest poprawne?

Teraz jest część, która mnie dezorientuje:

Jeśli biegnę GC z Android Studio, pamięć jest czyszczona prawidłowo i nigdy moja aktywność zostaje zamknięty. Po prostu trzeba użyć GC z Androidem, kiedy przydzielono dużo pamięci. enter image description here

Jest to jeden Znaczy:

enter image description here

Ogólnie pytanie brzmi:

Dlaczego Android Studio GC oczyścić pamięć i dlaczego właściwie nie robi działa poprawnie z automatycznym GC z Androidem?

Wiem, że to dość ogólne pytanie. Chcę tylko wiedzieć, czy istnieją różne rodzaje śmieci czy coś takiego.

Również wywołanie System.gc(); nie powoduje właściwego wyczyszczenia pamięci.

Informacje dodatkowe:

Moto G 2-ty gen

Android 5.0.2.

+0

"Czasami działanie lub aplikacja zamyka się. Myślałem, że może to być spowodowane problemami z pamięcią." Jeśli aplikacja zginie b/c, gdy zabraknie jej pamięci, otrzymasz wyjątek Out-of Memory, który możesz wyraźnie zobaczyć w Logcat. Mam przeczucie, że twoja aplikacja ulega awarii z innego powodu. Spróbuj przejrzeć logcat, aby zobaczyć przyczynę awarii. – Shmuel

+1

Równoczesne GC dokonuje tylko częściowego odbioru, aby nie powodować zauważalnych przerw. Jawne GC, takie jak wywołane przez Studio, wykonuje pełny zakres GC. Niektóre czytania: https://source.android.com/devices/tech/dalvik/gc-debug.html – laalto

+0

@Shmuel Nie ma wyjątków. Nawet ostrzeżenia. – FlanschiFox

Odpowiedz

2

Być może możesz spróbować jednoznacznie dzwonić pod numer System.gc(); w swoim ciężkim kodzie przetwarzania?

+0

Przepraszam, że o tym zapomniałem. Próbowałem tego i nie działa. – FlanschiFox

+0

Jeśli rzeczywiście występuje wyciek pamięci, wywołanie System.gc() nie pomoże b/c pamięć będzie nadal utrzymywana przez odniesienie gdzieś w kodzie. – Shmuel

+0

@Shmuel Prawda, ale OP mówi, że aplikacja nie zawiesza się, gdy naciska przycisk GC w androidowym studio, które, jak sobie wyobrażam, dzwoni do "System.gc()", stąd moja sugestia. –

4

Przecieki pamięci mogą się zdarzyć z kilku powodów. Jednym z typowych powodów są bitmapy, które nie są prawidłowo przetwarzane. Innym źródłem wycieków pamięci jest zachowanie kontekstu w obiektach. Na przykład uruchamiasz zadanie asynchroniczne i przekazujesz kontekst, ponieważ potrzebujesz go później. Podczas działania zadania asynchronicznego zachowuje odwołanie do kontekstu, więc cała aktywność jest w pamięci. Jest to również bardzo częste w przypadku anonimowych i wewnętrznych klas, które mają odniesienie do klasy nadrzędnej, która zwykle jest fragmentem lub działaniem.

Proponuję użyć kanalizacji przecieku biblioteki, aby wykryć przecieki pamięci i użyć narzędzi Android do śledzenia przydziałów, aby dokładnie odkryć miejsce wycieku pamięci.

+0

Dzięki za odpowiedź. Wspomniałeś o typowych przyczynach powstawania wycieków pamięci. Zasadniczo jest to wszystko z powodu prawidłowych referencji. Ale w moim przypadku wywołanie Android Studio GC porządkuje wszystko poprawnie. Więc jeśli są jakieś dziwne odniesienia, GC nie powinien być w stanie ich oczyścić, prawda? – FlanschiFox

+0

Niezupełnie. Możesz opuścić jedno działanie, ale zachować referencję przez kilka sekund. Więc kiedy uruchomisz GC po kilku sekundach, wyczyścisz tę pamięć. Zmierzyłem się z sytuacjami, w których wróciłem z kilku działań i miałem przepełnienie pamięci, ponieważ być może bitmapa była poddawana recyklingowi i opóźniała GC, aby zwolnić pamięć, a więc wydostała się z pamięci. Domyślnie GC nie zwalnia pamięci, jeśli nie jest to konieczne (nie osiąga maksymalnej dozwolonej ilości pamięci). To może być również twój inny problem. – jorgemf

+0

Cieszę się, że widzę ten wątek i jest całkiem nowy. Czy @oberflansch znalazł przyczynę, dla której GC z tego studia działa lepiej? Pracuję nad tą samą sytuacją, w której aplikacja wyrzuca mnie z pamięci i program się zawiesza. Jedną z rzeczy, które znalazłem w mojej aplikacji, powodującą problem z pamięcią, było to, że wszystkie obrazy PNG, których używam w zasobach, są zbyt duże. Zastanawiam się, dlaczego android nie sam GC po zamknięciu działania, nawet wszystkie odwołania w klasie są rzeczywiście zamknięte ... pamięć stale rośnie za każdym razem, gdy tworzona jest nowa aktywność, aż do śmierci. –

Powiązane problemy