Referências fracas em Java

Referências fracas em Java

1. Visão geral

Neste artigo, daremos uma olhada no conceito de referência fraca - na linguagem Java.

Vamos explicar o que são, para que são usados ​​e como trabalhar com eles de maneira adequada.

2. Referências Fracas

Um objeto fracamente referenciado é limpo pelo Coletor de Lixo quando está fracamente acessível.

Acessibilidade fraca significa que umobject has neither strong nor soft references pointing to it. O objeto pode ser alcançado apenas atravessando uma referência fraca.

Primeiro, o Garbage Collector limpa uma referência fraca, para que o referente não esteja mais acessível. Em seguida, a referência é colocada em uma fila de referência (se houver alguma associada) de onde podemos obtê-la.

Ao mesmo tempo, objetos anteriormente pouco alcançáveis ​​serão finalizados.

3. Casos de Uso

Conforme declarado pela documentação Java,weak references are most often used to implement canonicalizing mappings. Um mapeamento é chamado canonicalizado se tiver apenas uma instância de um valor específico. Em vez de criar um novo objeto, ele pesquisa o existente no mapeamento e o utiliza.

Claro, omost known use of these references is the WeakHashMap class. É a implementação da interfaceMap onde cada chave é armazenada como uma referência fraca para a chave fornecida. Quando o Garbage Collector remove uma chave, a entidade associada a essa chave também é excluída.

Para obter mais informações, verifiqueour guide to WeakHashMap.

Outra área onde eles podem ser usados ​​éthe Lapsed Listener problem.

Um editor (ou um assunto) mantém fortes referências a todos os assinantes (ou ouvintes) para notificá-los sobre os eventos que aconteceram. The problem arises when a listener can’t successfully unsubscribe from a publisher.

Portanto, um ouvinte não pode ser coletado como lixo, pois uma referência forte a ele ainda está disponível para um editor. Conseqüentemente, vazamentos de memória podem ocorrer.

A solução para o problema pode ser um assunto com uma referência fraca para um observador, permitindo que o primeiro seja coletado no lixo sem a necessidade de cancelar a inscrição (note que esta não é uma solução completa e introduz alguns outros problemas que não são coberto aqui).

4. Trabalho com referências fracas

Referências fracas são representadas pela classejava.lang.ref.WeakReference. Podemos inicializá-lo passando um referente como parâmetro. Opcionalmente, podemos fornecer umjava.lang.ref.ReferenceQueue:

Object referent = new Object();
ReferenceQueue referenceQueue = new ReferenceQueue<>();

WeakReference weakReference1 = new WeakReference<>(referent);
WeakReference weakReference2 = new WeakReference<>(referent, referenceQueue);


O referente de uma referência pode ser obtido pelo métodoget e removido manualmente usando o métodoclear:

Object referent2 = weakReference1.get();
weakReference1.clear();

O padrão para trabalhar com segurança com este tipo de referências é o mesmo que comsoft references:

Object referent3 = weakReference2.get();
if (referent3 != null) {
    // GC hasn't removed the instance yet
} else {
    // GC has cleared the instance
}

5. Conclusão

Neste tutorial rápido, vimos o conceito de baixo nível de uma referência fraca em Java - e focamos nos cenários mais comuns para usá-los.