2013-05-23 14 views
7

Chcę używać WeakReference s jako część (android) bitmapy-cache, aby móc sprawdzić, kiedy bitmapa nie jest już używana.Kiedy WeakReference # get() zaczyna zwracać wartość null?

Moja pamięć podręczna ma maksymalny rozmiar, który jest mniejszy niż przestrzeń sterty Java. Kiedy nowa bitmapa przepełni pamięć podręczną, powinna puścić mapy bitowe, które nie są już potrzebne.

Moje pytanie: Kiedy metoda get() z WeakReference zwraca wartość null?

  1. Jak tylko nie ma już silnych odniesień do obiektu? (i GC jeszcze się nie wydarzyło)
  2. Lub kiedy GC już działa i stwierdza, że ​​ich nie ma więcej silnych odniesień do obiektu?

Jeśli 2. jest prawdą, mógłbym natknąć się na sytuację, w której moja pamięć podręczna mogłaby się wypełnić, a GC nie działała ostatnio z jakiegoś powodu.

Następnie, nawet jeśli już zwolniłem referencje PO ostatnim biegu GC, WeakReference#get() nadal zwróci obiekt, a moja pamięć podręczna go nie wyczyści.

Odpowiedz

10

Odpowiedź jest zależna od wersji Androida, z której korzystasz. Gdzieś w 2.3 okresie, Android zmienił obsługę lub słabe referencje. Wcześniej usuwał je, gdy uruchomiono GC. Od wersji 2.3 (2.3.3?) Zaczęło usuwać je natychmiast po odejściu ostatniego silnego odniesienia. W nowoczesnych wersjach Androida słabe referencje są bezużyteczne.

Przed tą zmianą do buforowania użyto słabych odniesień. Już nie działają. Prawidłowym sposobem jest teraz użycie LRUCache. Jeśli potrzebujesz obsługi starszych wersji, skorzystaj z biblioteki pomocy, aby zarchiwizować pamięć podręczną LRU.

Po pewnym przeszukaniu, myślę, że zmiana została dokonana w wersji 3.0, a nie 2.3. Mimo to rozwiązanie jest takie samo.

+0

Miękkie odniesienia są przeznaczone do buforowania. Jakie są ich zachowania w systemie Android? –

+2

To samo - są one uwalniane, gdy tylko nie ma silnych odniesień. Który podąża za listem standardu Java, jeśli nie duchem. –

+0

Zmiana dotyczyła poziomu interfejsu API 9. Odpowiednia dokumentacja: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html#memory-cache – Delyan

5

Funkcja WeakReference jest czyszczona, gdy tylko GC ustali, że obiekt jest słabo dostępny.

To jest blisko twojego drugiego przypadku. Jednak słaba dostępność wymaga nie tylko braku silnych odniesień, ale także braku miękkich odniesień.

Z dokumentacji pakietu Java dla java.lang.ref:

referencje miękkie i słabe są automatycznie usuwane przez kolektor przed dodaniem do kolejki, z którymi są one zarejestrowane, jeśli w ogóle.

...

Obiekt jest słabo osiągalny, jeśli to nie jest ani silnie ani miękko osiągalny ale może być osiągnięty przez przejeżdżające słabego odniesienia. Po usunięciu słabych odniesień do słabo osiągalnego obiektu obiekt kwalifikuje się do finalizacji.

+1

To prawda z punktu widzenia języka Java, ale nie cała historia Androida. Zobacz mój post na temat tego, jak Android implementuje je i jak się zmieniał w przeszłości. –

4

Do buforowania bitmap użyj SoftReference zamiast Słaby. GC usunie WeakReference, gdy tylko straci wszystkie silne i miękkie odniesienia, które mogą zniszczyć cel buforowania. Opcja SoftReference jest czyszczona tylko w przypadku małej ilości pamięci. Gwarantuje się, że GC zostanie uruchomiony przed wyrzuceniem OOME.

+0

+1 - Powinienem był o tym wspomnieć, po tym, gdy musiałem zamienić słabe odniesienia w bibliotece na miękkie. –

-3

Jak stwierdzono w innych odpowiedziach, WeakReference zwróci wartość null, gdy wskazany obiekt nie ma już silnych/miękkich odniesień i GC odzyskał pamięć.

Na zasadzie bardziej ogólnej, nie sądzę, Weak/SoftReferences są dobre w aplikacji. To sprawia, że ​​swoje obawy mix:

  • Aplikacja jest o logiki biznesowej
  • JVM i Dalvik są o zarządzaniu pamięcią i optymalizacji kodu.

Po uruchomieniu używania słabych/miękkich odniesień, wprowadzasz do swojej aplikacji problemy z zarządzaniem pamięcią, co utrudnia tworzenie/debugowanie/rozumienie.

Zamiast tego możesz chcieć mieć rozmiar LRU o stałej wielkości (liczba elementów lub rozmiar mapy bitowej).

Nadzieję, że pomaga!

+2

Gabe Sechan zapewnia najlepszą odpowiedź dla Androida. Gdzie indziej aplikacje zawierają więcej niż logikę biznesową, a Weak/SoftReferences mają swoje zastosowania. –

+2

"Twoja aplikacja dotyczy logiki biznesowej" jest nieco domniemana. Aplikacje mobilne nie zawsze są opakowaniami typu "web-service", a słabe referencje są kluczową koncepcją w Volatile Caching, która znajduje wiele zastosowań w aplikacjach krytycznych pod względem wydajności, zarówno po stronie mobilnej, jak i serwerowej. –

Powiązane problemy