Riferimenti soft in Java

1. Panoramica

In questo rapido articolo, parleremo di riferimenti morbidi in Java.

Spiegheremo cosa sono, perché ne abbiamo bisogno e come crearli.

2. Cosa sono i riferimenti soft?

Un oggetto di riferimento flessibile (o un oggetto raggiungibile in modo flessibile) può essere cancellato dal Garbage Collector in risposta a una richiesta di memoria. Un oggetto dolcemente raggiungibile non ha riferimenti forti che lo puntino .

Quando viene chiamato un Garbage Collector, inizia l'iterazione su tutti gli elementi nell'heap. GC memorizza gli oggetti di tipo di riferimento in una coda speciale.

Dopo che tutti gli oggetti nell'heap sono stati controllati, GC determina quali istanze devono essere rimosse rimuovendo gli oggetti da quella coda menzionata sopra.

Queste regole variano da un'implementazione JVM all'altra, ma la documentazione afferma che è garantito che tutti i riferimenti software a oggetti raggiungibili in modo flessibile siano cancellati prima che una JVM generi un OutOfMemoryError.

Tuttavia, non viene data alcuna garanzia sul momento in cui un riferimento morbido viene cancellato o sull'ordine in cui un insieme di tali riferimenti a oggetti diversi viene cancellato.

Di norma, le implementazioni JVM scelgono tra la pulizia dei riferimenti creati di recente o utilizzati di recente.

Gli oggetti facilmente raggiungibili rimarranno vivi per un po 'di tempo dopo l'ultima volta in cui sono stati referenziati. Il valore predefinito è un secondo di durata per megabyte libero nell'heap. Questo valore può essere modificato utilizzando il flag -XX: SoftRefLRUPolicyMSPerMB .

Ad esempio, per modificare il valore in 2,5 secondi (2500 millisecondi), possiamo utilizzare:

-XX:SoftRefLRUPolicyMSPerMB=2500

Rispetto ai riferimenti deboli, i riferimenti flessibili possono avere una durata maggiore poiché continuano a esistere fino a quando non è necessaria memoria aggiuntiva.

Pertanto, sono una scelta migliore se abbiamo bisogno di mantenere gli oggetti in memoria il più a lungo possibile.

3. Casi d'uso dei riferimenti soft

I riferimenti trasferibili possono essere utilizzati per implementare cache sensibili alla memoria in cui la gestione della memoria è un fattore molto importante.

Finché il referente di un riferimento soft è fortemente raggiungibile, cioè - è effettivamente in uso, il riferimento non verrà cancellato.

Una cache può, ad esempio, impedire che le voci utilizzate più di recente vengano eliminate mantenendo forti riferimenti a tali voci, lasciando che le voci rimanenti vengano eliminate a discrezione del Garbage Collector.

4. Lavorare con riferimenti morbidi

In Java, un riferimento software è rappresentato dalla classe java.lang.ref.SoftReference .

Abbiamo due opzioni per inizializzarlo.

Il primo modo è passare solo un referente:

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

La seconda opzione implica il passaggio di un riferimento a java.lang.ref.ReferenceQueue e un riferimento a un referente. Le code di riferimento sono progettate per renderci consapevoli delle azioni eseguite dal Garbage Collector. Aggiunge un oggetto di riferimento a una coda di riferimento quando decide di rimuovere il referente di questo riferimento.

Ecco come inizializzare un SoftReference con una ReferenceQueue:

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

Come java.lang.ref.Reference , contiene rispettivamente i metodi get e clear per ottenere e reimpostare un referente:

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

Ogni volta che lavoriamo con questo tipo di riferimenti, dobbiamo assicurarci che sia presente un referente, restituito dal get :

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

5. conclusione

In questo tutorial, abbiamo acquisito familiarità con il concetto di riferimenti soft e i loro casi d'uso.

Inoltre, abbiamo imparato come crearne uno e lavorarci a livello di programmazione.