7

Spędziłem prawie cały dzień próbując odkryć przyczynę wycieku pamięci w systemie Android. Jest aktywność, którą otwieram/zamykam wiele razy (z timerem). Po chwili był już OutOfMemory błędy:Czy nie powinno zabraknąć GC automatycznie w Xamarin.Android, zanim zabraknie pamięci?

enter image description here

Widziałem pamięć dzieje się stale w Xamarin Profiler każdym razem aktywność otworzony

enter image description here

Upewniłem nie było żadnych właściwości lub programy obsługi zdarzeń, które mogą utknąć w tej czynności. Nawet usunąłem wszystkie obrazy, przyciski itp., Próbując wykryć przyczynę wycieku pamięci. Wciąż to samo ...

Potem zrobiłem GC.Collect() w metodzie głównej aktywności OnResume (tej, która otwiera problematyczne działanie). Teraz widzę, jak pamięć zaczyna się w górę iw dół, tak jak powinna. Można zobaczyć wynik w zrzucie:

enter image description here

zgodnie Xamarin docs:

GC będzie działał, gdy małoletni sterty zabrakło pamięci na nowe przydziały

Ale tak się nie dzieje:

+3

Stosowna czytanie: https://developer.xamarin.com/guides/android/advanced_topics/garbage_collection/#Cross-VM_Object_Collections i http://stackoverflow.com/questions/ 28863058/xamarin-android-finalizer-nie-wywołanie-kiedy-opuszczenie-działania-do-przejścia-do/28868582 # 28868582 – matthewrdev

Odpowiedz

9

Możesz przeczytać nieco dalej w linku poniżej Pomaganie GC: The GC has an incomplete view of the process and may not run when memory is low because the GC doesn't know that memory is low. i Managed Callable Wrappers do not add additional instance members

Zasadniczo wydaje BaseActivity jest Android Callable Wrapper (ACW) i Mono GC nie wie, jak duże to jest, więc nie wiem, aby wywołać śmieciarz. Z tego co wiem, ACW to sposób na wdrożenie interfejsów Android.

Rozwiązaniem jest ręczne wywołanie kosza, który jest zalecany w dokumentach Xamarin podczas korzystania z ACW.

http://developer.xamarin.com/guides/android/advanced_topics/garbage_collection/

----

Od oryginalnego delegowania tej odpowiedzi, docs Xamarin poprawiły się w ich wyjaśnienia tej sytuacji:

Instancja Java TypLang.Object lub typ wyprowadzenia to o rozmiarze co najmniej 20 bajtów. Managed Callable Wrappers nie dodają dodatkowych instancji członków, więc jeśli masz instancję Android.Graphics.Bitmap, która jest odnosi się do 10-MB blob pamięci, Xamarin.Android's GC nie będzie wiedział, że - GC zobaczy 20- obiekt bajtowy i nie będzie w stanie określić, czy jest on połączony z obiektami alokowanymi w środowisku wykonawczym z systemem Android, które utrzymują pamięć o wartości 10 MB.

To wskazuje, że niezależnie od tego czy obiekty są ustawione na null lub nie, należy nadal ręcznie wywołać Xamarin GC jeśli alokacji/dealokując wywoływalnym Owijarki które potencjalnie mogą spożywać dużej ilości pamięć.

Działając zgodnie z założeniem, że Java Object ma 20 bajtów, jeśli jeden z nich przydzieli i null 100 obiektów, które zużywają po 10 MB, Xamarin GC uważa, że ​​4000 bajtów pamięci jest w użyciu. W rzeczywistości używa się ~ 1 GB, a GC może, ale nie musi, zostać wywołany.

-3

Wywołanie funkcji czyszczenia pamięci nie gwarantuje, że zostanie uruchomione usuwanie śmieci lub że wystąpią wszystkie alokacje pamięci. Wiele razy chodzi o usunięcie odniesienia do obiektu. Jeśli obiekt ma odniesienie do niego, nie będzie to zbiórka śmieci. Musiałem się tego nauczyć na własnej skórze. Zasadniczo, aby rozwiązać ten problem w dowolnym momencie, możesz usunąć obiekt w dowolnym momencie i ustawić go, gdy zajdzie taka potrzeba. Przykład:

CustomObject cusObj = null; 
if (cusObj == null) 
{ 
    cusObj = new CustomObject(); 
} 

Po prostu upewniając się, że null out obiektu usuwa odniesienia. Ale jak stwierdzono w powyższej odpowiedzi, możesz także zbierać śmieci. Pamiętaj tylko, że GC nie będzie marnotrawił przedmiotu z referencją. Spójrz:

Garbage collection and references C#

+0

Jak można przeczytać w pytaniu, nie jest to problem referencyjny, ponieważ upewniłem się, że wszystko, co jest w porządku – xleon

+0

Nieprawdą Największą przyczyną błędów miejsca sterty są odniesienia do obiektów, które nie pozwolą, aby śmieciarz wykonał tam pracę. – yams

+0

Wyrzucenie twoich obiektów w celu pozbycia się odniesienia pomogłoby w rozwiązaniu problemu. – yams