SoftReference za wcześnie zbiera śmieci

Jestem w drodze z implementacją mechanizmu buforowania dla mojej aplikacji na Androida.

Używam SoftReference, jak wiele przykładów, które znalazłem. Problem polega na tym, że gdy przewijam w górę lub w dół w moim ListView, większość obrazów jest już wyczyszczona. Widzę w LogCat, że moja aplikacja jest śmieci zbierane za każdym razem, gdy aplikacja ładuje nowe obrazy. Oznacza to, że większość z niewidocznych obrazów w ListView zniknęła.

Więc za każdym razem ja przewiń w tył do wcześniejszą pozycję (gdzie naprawdę ściągałem wcześniej obrazki) muszę ściągnąć obrazki jeszcze raz-są Nie cached .

Zbadałem również ten temat. według Marka Murphy ' ego w tym artykule, wydaje się, że jest (lub było?) błąd z SoftReference. Niektóre inne wyniki wskazują na to samo (lub ten sam wynik); SoftReference S są usuwane zbyt wcześnie.

Czy istnieje jakieś działające rozwiązanie?

Author: Wroclai, 2011-04-22

4 answers

SoftReference są biedne Mans Cache. JVM może utrzymać te odniesienia dłużej, ale nie musi. Jak tylko nie ma już twardego odniesienia, JVM może pobierać miękki obiekt odniesienia. Zachowanie JVM, którego doświadczasz, jest poprawne, ponieważ JVM nie musi dłużej trzymać takiego obiektu. Oczywiście większość JVMs stara się utrzymać miękki obiekt odniesienia przy życiu do pewnego stopnia.

Dlatego Softreferencje są rodzajem niebezpiecznej pamięci podręcznej. Jeśli naprawdę chcesz zapewnić zachowanie buforowania, potrzebujesz prawdziwej pamięci podręcznej. Jak LRU-cache . Zwłaszcza jeśli buforowanie ma kluczowe znaczenie dla wydajności, powinieneś użyć odpowiedniej pamięci podręcznej.

 16
Author: Gamlor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:58:30

From Android Training site:

Http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

W przeszłości, popularna implementacja pamięci podręcznej była SoftReference lub WeakReference bitmap cache, jednak nie jest to zalecane. Począwszy od Androida 2.3 (poziom API 9) garbage collector jest bardziej agresywne ze zbieraniem miękkich / słabych odniesień, co czyni je dość nieskuteczne . Ponadto przed Androidem 3.0 (API poziom 11), dane zapasowe bitmapy były przechowywane w pamięci natywnej, która nie jest wydany w sposób przewidywalny, potencjalnie powodujący wystąpienie aby na krótko przekroczyć granice pamięci i zawiesić.

Więcej informacji w linku.

Zamiast tego możemy użyć LruCache.

 7
Author: fones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-13 10:46:16

Buforuj każdy obraz na trwałej pamięci, a nie tylko w pamięci.

 2
Author: Mike dg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-22 17:17:34

Odpowiedź Gamlora jest prawidłowa w Twoim situtacji. Jednakże, aby uzyskać dodatkowe informacje, zobacz GC FAQ , pytanie 32.

Maszyna wirtualna Java HotSpot Server używa maksymalnego możliwego rozmiaru sterty (ustawionego przez opcję-Xmx) do obliczenia pozostałego wolnego miejsca.

Maszyna wirtualna klienta Java HotSpot wykorzystuje bieżący rozmiar sterty do obliczenia wolnego miejsca.

Oznacza to, że ogólna tendencja polega na tym, aby serwer vm powiększał stertę, a nie spłukiwał miękkie referencje, i dlatego-Xmx ma znaczący wpływ na to, kiedy miękkie odwołania są zbierane.

 1
Author: tylermac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-16 06:46:05