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.