Referências suaves em Java

Referências suaves em Java

1. Visão geral

Neste artigo rápido, falaremos sobre referências soft em Java.

Explicaremos o que são, por que precisamos deles e como criá-los.

2. O que são referências flexíveis?

Um objeto de referência programável (ou um objeto facilmente alcançável) pode ser limpo pelo Garbage Collector em resposta a uma demanda de memória. A softly reachable object has no strong references pointing to it.

Quando um Garbage Collector é chamado, ele começa a iterar sobre todos os elementos no heap. O GC armazena objetos do tipo de referência em uma fila especial.

Após a verificação de todos os objetos no heap, o GC determina quais instâncias devem ser removidas removendo os objetos da fila mencionada acima.

Essas regras variam de uma implementação JVM para outra, mas a documentação afirma queall soft references to softly-reachable objects are guaranteed to be cleared before a JVM throws an OutOfMemoryError.

No entanto, nenhuma garantia é dada no momento em que uma referência suave é limpa ou na ordem em que um conjunto dessas referências a diferentes objetos é limpo.

Como regra, as implementações da JVM escolhem entre a limpeza de referências criadas recentemente ou usadas recentemente.

Objetos levemente alcançáveis ​​permanecerão ativos por algum tempo após a última vez em que forem referenciados. O valor padrão é um segundo de vida útil por megabyte grátis no heap. Este valor pode ser ajustado usando o sinalizador-XX:SoftRefLRUPolicyMSPerMB.

Por exemplo, para alterar o valor para 2,5 segundos (2500 milissegundos), podemos usar:

-XX:SoftRefLRUPolicyMSPerMB=2500

Em comparação com referências fracas, as referências flexíveis podem ter vida útil mais longa, pois continuam a existir até que seja necessária memória extra.

Portanto, eles são uma escolha melhor se precisarmos manter objetos na memória o maior tempo possível.

3. Casos de uso de Soft References

Soft references can be used for implementing memory-sensitive caches onde o gerenciamento de memória é um fator muito importante.

Contanto que o referente de uma referência suave seja fortemente alcançável, isto é - está realmente em uso, a referência não será apagada.

Um cache pode, por exemplo, impedir que suas entradas usadas mais recentemente sejam descartadas mantendo referências fortes a essas entradas, deixando as entradas restantes a serem descartadas a critério do Garbage Collector.

4. Trabalho com referências suaves

Em Java, uma referência de software é representada pela classejava.lang.ref.SoftReference.

Temos duas opções para inicializá-lo.

A primeira maneira é passar apenas um referente:

StringBuilder builder = new StringBuilder();
SoftReference reference1 = new SoftReference<>(builder);

A segunda opção implica passar uma referência ajava.lang.ref.ReferenceQueue, bem como uma referência a um referente. Reference queues are designed for making us aware of actions performed by the Garbage Collector. Ele anexa um objeto de referência a uma fila de referência conforme decide remover o referente desta referência.

Veja como inicializar umSoftReference com umReferenceQueue:

ReferenceQueue referenceQueue = new ReferenceQueue<>();
SoftReference reference2
 = new SoftReference<>(builder, referenceQueue);

Comojava.lang.ref.Reference, ele contém os métodosgeteclear para obter e redefinir um referente, respectivamente:

StringBuilder builder1 = reference2.get();
reference2.clear();
StringBuilder builder2 = reference2.get(); // null

Cada vez que trabalhamos com este tipo de referências, precisamos ter certeza de que um referente, retornado porget, está presente:

StringBuilder builder3 = reference2.get();
if (builder3 != null) {
    // GC hasn't removed the instance yet
} else {
    // GC has cleared the instance
}

5. Conclusão

Neste tutorial, nos familiarizamos com o conceito de referências simples e seus casos de uso.

Além disso, aprendemos como criar um e trabalhar com ele de maneira programática.