Zwakke referenties in Java

1. Overzicht

In dit artikel zullen we het concept van een zwakke referentie bekijken - in de Java-taal.

We gaan uitleggen wat deze zijn, waarvoor ze worden gebruikt en hoe je er op de juiste manier mee kunt werken.

2. Zwakke referenties

Een object met een zwakke verwijzing wordt gewist door de Garbage Collector wanneer het zwak bereikbaar is.

Zwakke bereikbaarheid betekent dat een object heeft geen sterke of zachte verwijzingen die ernaar verwijzen. Het object kan alleen worden bereikt door een zwakke referentie te passeren.

Ten eerste wist de Garbage Collector een zwakke referentie, zodat de referent niet langer toegankelijk is. Vervolgens wordt de referentie in een referentiewachtrij geplaatst (als die er is) waar we deze vandaan kunnen halen.

Tegelijkertijd zullen voorheen zwak bereikbare objecten worden afgerond.

2.1. Zwakke versus zachte referenties

Soms is het verschil tussen zwakke en zachte referenties onduidelijk. Zachte verwijzingen zijn in feite een grote LRU-cache. Dat is, we gebruiken zachte referenties wanneer de referent een goede kans heeft om in de nabije toekomst te worden hergebruikt.

Aangezien een zachte referentie fungeert als een cache, kan deze bereikbaar blijven, zelfs als de referent zelf dat niet is. In feite komt een zachte referentie in aanmerking voor incasso als en alleen als:

  • De referent is niet goed bereikbaar
  • De zachte referentie is onlangs niet geopend

Een zachte referentie kan dus minuten of zelfs uren beschikbaar zijn nadat de referent onbereikbaar is geworden. Aan de andere kant is een zwakke referentie alleen beschikbaar zolang de referent er nog is.

3. Gebruik cases

Zoals vermeld in de Java-documentatie, zwakke verwijzingen worden meestal gebruikt om canonieke toewijzingen te implementeren. Een mapping wordt canonicalized genoemd als deze slechts één exemplaar van een bepaalde waarde bevat. In plaats van een nieuw object te maken, zoekt het het bestaande op in de mapping en gebruikt het.

Natuurlijk is de meest bekende gebruik van deze referenties is de WeakHashMap klasse. Het is de implementatie van het Kaart interface waar elke sleutel wordt opgeslagen als een zwakke verwijzing naar de gegeven sleutel. Wanneer de Garbage Collector een sleutel verwijdert, wordt de entiteit die aan deze sleutel is gekoppeld ook verwijderd.

Raadpleeg onze gids voor WeakHashMap voor meer informatie.

Een ander gebied waar ze kunnen worden gebruikt, is het probleem met de vervallen luisteraar.

Een uitgever (of een onderwerp) bevat sterke verwijzingen naar alle abonnees (of luisteraars) om hen op de hoogte te stellen van gebeurtenissen die hebben plaatsgevonden. Het probleem doet zich voor wanneer een luisteraar zich niet met succes kan afmelden bij een uitgever.

Daarom kan een luisteraar niet als afval worden verzameld, omdat een sterke verwijzing ernaar nog steeds beschikbaar is voor een uitgever. Bijgevolg kunnen er geheugenlekken optreden.

De oplossing voor het probleem kan een onderwerp zijn met een zwakke verwijzing naar een waarnemer die toestaat dat de eerste als vuilnis wordt opgehaald zonder dat u zich hoeft af te melden (merk op dat dit geen volledige oplossing is, en het introduceert enkele andere problemen die dat niet zijn hier behandeld).

4. Werken met zwakke referenties

Zwakke referenties worden vertegenwoordigd door de java.lang.ref.WeakReference klasse. We kunnen het initialiseren door een referent als parameter door te geven. Optioneel kunnen we een java.lang.ref.ReferenceQueue:

Object referent = nieuw object (); ReferenceQueue referenceQueue = nieuwe ReferenceQueue (); WeakReference zwakkeReference1 = nieuwe WeakReference (referent); WeakReference zwakkeReference2 = nieuwe WeakReference (referent, referenceQueue); 

De referent van een referentie kan worden opgehaald door de krijgen methode, en handmatig verwijderd met behulp van de Doorzichtig methode:

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

Het patroon voor veilig werken met dit soort referenties is hetzelfde als bij zachte referenties:

Object referent3 = zwakkeReference2.get (); if (referent3! = null) {// GC heeft de instantie nog niet verwijderd} else {// GC heeft de instantie gewist}

5. Conclusie

In deze korte tutorial hebben we het low-level concept van een zwakke referentie in Java bekeken - en ons gefocust op de meest voorkomende scenario's om deze te gebruiken.