8.1 Referências fracas em Java
Existem vários tipos de referências em Java.
Existe o StrongReference - esses são os links mais comuns que criamos todos os dias.
Object object = new Object();//created an object
object = null;//can now be garbage collected
E existem três tipos "especiais" de links - SoftReference, WeakReference, PhantomReference. Na verdade, existe apenas uma diferença entre todos os tipos de links - o comportamento do GC com os objetos aos quais eles se referem. Discutiremos as especificidades de cada tipo de link com mais detalhes posteriormente, mas, por enquanto, o seguinte conhecimento será suficiente:
- SoftReference é uma referência suave, se o GC perceber que um objeto só é acessível por meio de uma cadeia de referências suaves, ele o removerá da memória. Talvez.
- WeakReference - uma referência fraca, se o GC perceber que um objeto só é acessível por meio de uma cadeia de referências fracas, ele o removerá da memória.
- PhantomReference é uma referência fantasma, se o GC perceber que um objeto só está disponível por meio de uma cadeia de referências fantasmas, ele o removerá da memória. Depois de várias execuções de GC.
Você também pode dizer que os tipos de link têm um certo grau de suavidade:
- Um hard link regular é qualquer variável de um tipo de referência. Não limpo pelo coletor de lixo antes de se tornar inutilizado.
- SoftReference . O objeto não fará com que toda a memória seja usada - é garantido que ele será excluído antes que ocorra um OutOfMemoryError. Talvez antes, dependendo da implementação do coletor de lixo.
- Referência Fraca . Suave mais fraco. Não impede que o objeto seja descartado; o coletor de lixo ignora essas referências.
- PhantomReference . Usado para processamento de "morte" de um objeto: o objeto fica disponível após a finalização até que seja coletado como lixo.
Se ainda não está claro qual é a diferença, não se preocupe, logo tudo se encaixará. Os detalhes estão nos detalhes, e os detalhes se seguirão.
8.2 WeakReference e SoftReference em Java
Primeiro, vamos ver a diferença entre WeakReference e SoftReference em Java.
Resumindo, o coletor de lixo liberará a memória de um objeto se apenas referências fracas apontarem para ele. Se o objeto for apontado por SoftReferences, a memória será desalocada quando a JVM precisar urgentemente de memória.
Isso dá uma vantagem definitiva ao SoftReference sobre a referência Strong em certos casos. Por exemplo, SoftReference é usado para implementar um cache de aplicativo, portanto, a primeira coisa que a JVM fará é excluir objetos para os quais somente SoftReferences apontam.
WeakReference é ótimo para armazenar metadados, como armazenar uma referência a um ClassLoader. Se nenhuma classe for carregada, você não deve consultar o ClassLoader. É por isso que WeakReference permite que o coletor de lixo faça seu trabalho no ClassLoader assim que a última referência forte a ele for removida.
Exemplo de WeakReference em Java:
// some object
Student student = new Student();
// weak reference to it
WeakReference weakStudent = new WeakReference(student);
// now the Student object can be garbage collected
student = null;
Exemplo SoftReference em Java:
// some object
Student student = new Student();
// weak reference to it
SoftReference softStudent = new SoftReference(student)
// now the Student object can be garbage collected
// but this will only happen if the JVM has a strong need for memory
student = null;
8.3 PhantomReference em Java
A instância PhantomReference é criada da mesma forma que nos exemplos WeakReference e SoftReference, mas raramente é usada.
Uma PhantomReference pode ser coletada como lixo se o objeto não tiver referências fortes (Strong), fracas (WeakReference) ou soft (SoftReference).
Você pode criar um objeto Phantom Reference como este:
PhantomReference myObjectRef = new PhantomReference(MyObject);
PhantomReference pode ser usado em situações onde finalize() não faz sentido. Esse tipo de referência é diferente de outros tipos porque não foi projetado para acessar um objeto. É um sinal de que o objeto já foi finalizado e o coletor de lixo está pronto para recuperar sua memória.
Para fazer isso, o coletor de lixo o coloca em uma ReferenceQueue especial para processamento posterior. ReferenceQueue é onde as referências de objeto são colocadas para liberar memória.
Referências fantasmas são uma maneira segura de saber que um objeto foi removido da memória. Por exemplo, considere um aplicativo que lida com imagens grandes. Digamos que queremos carregar uma imagem na memória quando ela já estiver na memória, que está pronta para a coleta de lixo. Nesse caso, queremos esperar que o coletor de lixo elimine a imagem antiga antes de carregar a nova imagem na memória.
Aqui PhantomReference é uma escolha flexível e segura. A referência à imagem antiga será passada para o ReferenceQueue depois que o objeto da imagem antiga for destruído. Assim que tivermos esse link, podemos carregar a nova imagem na memória.