Java Academy · Les

Geheugenlekken detecteren en verhelpen

Identificeer veelvoorkomende patronen van geheugenlekken (statische collecties, listeners, caches) en verhelp ze.

Les 3 van 413 stappen

Geheugenlekken detecteren en verhelpen is een gratis Java Academy-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Java Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Java Academy bevat in totaal 4 lessen.

Wat is een geheugenlek in Java?

Een Java-geheugenlek ontstaat wanneer objecten niet meer nodig zijn maar sterk bereikbaar blijven, waardoor de GC ze niet kan terugwinnen. De heap groeit totdat een OutOfMemoryError wordt gegenereerd.

Ophoping in een statische verzameling

Een statisch veld met een groeiende verzameling is een klassiek lek. Objecten die worden toegevoegd maar nooit verwijderd, blijven in leven gedurende de levensduur van de toepassing.

public class Cache {
    // LEAK: static list grows forever if items are never removed
    private static final List<Object> items = new ArrayList<>();
    public static void add(Object o) { items.add(o); }
    // Fix: add a remove() method or use a bounded cache
}

Niet-geregistreerde gebeurtenislisteners

Als je een gebeurtenislistener registreert zonder deze ooit te verwijderen, blijven zowel de listener als alle objecten waarnaar deze verwijst in leven. Verwijder gebeurtenislisteners altijd wanneer je ze niet meer nodig hebt.

// Leak:
sensor.addListener(new DataLogger());
// Fix:
DataLogger logger = new DataLogger();
sensor.addListener(logger);
// ... when done:
sensor.removeListener(logger);

ThreadLocal-variabelen niet opgeruimd

In threadpools blijven ThreadLocal-waarden tussen taken bestaan omdat threads opnieuw worden gebruikt. Als je ze niet wist, lekken de gegevens van een taak door naar volgende taken op dezelfde thread.

private static final ThreadLocal<MyContext> CTX = new ThreadLocal<>();
// Always clean up after each task:
try {
    CTX.set(new MyContext(requestId));
    doWork();
} finally {
    CTX.remove(); // prevents leak in pooled threads
}

Classloaderlekken in apps met hot deployment

In servletcontainers gebruikt elke implementatie een nieuwe classloader. Als een klasse een statische verwijzing bevat naar een klasse uit de oude classloader, kan de volledige oude classloader, inclusief al zijn klassen, niet door de GC worden verzameld.

Lekken opsporen met heapdumps

Maak een heapdump met jmap -dump:format=b,file=heap.hprof <pid> en open die daarna in Eclipse MAT of VisualVM om de objecten te vinden die het meeste geheugen vasthouden en hun GC-roots te bekijken.

// Take a heap dump:
jmap -dump:live,format=b,file=heap.hprof $(jps | grep MyApp | cut -d" " -f1)
// Or trigger on OOM:
// -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heap.hprof

Eclipse Memory Analyzer (MAT)

Het rapport "Verdachte lekken" van MAT identificeert automatisch objecten die veel heapgeheugen vasthouden en toont het pad vanaf de GC-roots. Begin met de weergave "Dominatorboom" om de grootste boosdoeners te vinden.

Lekken voorkomen met WeakReference

Wikkel objecten uit caches of luisteraars in WeakReference. De GC kan ze bij geheugendruk terugwinnen. Controleer het resultaat van get() altijd op null.

Map<String, WeakReference<Image>> imageCache = new HashMap<>();
imageCache.put("logo", new WeakReference<>(loadImage("logo.png")));
Image logo = imageCache.get("logo") != null ? imageCache.get("logo").get() : null;
if (logo == null) logo = reload("logo.png"); // re-load if GCed

Caches met begrensde omvang en LinkedHashMap LRU

Overschrijf removeEldestEntry in een LinkedHashMap om de cachegrootte te begrenzen en het minst recent gebruikte item automatisch te verwijderen.

Map<String, String> lruCache = new LinkedHashMap<>(16, 0.75f, true) {
    protected boolean removeEldestEntry(Map.Entry<String, String> e) {
        return size() > 100; // evict when over 100 entries
    }
};

Geheugentoewijzingen profileren met Java Flight Recorder

JFR (Java Flight Recorder) legt profielen van geheugentoewijzingen vast met minimale extra belasting. Schakel het in met -XX:StartFlightRecording en analyseer de gegevens met JDK Mission Control.

// Start a 60-second JFR recording:
java -XX:StartFlightRecording=duration=60s,filename=rec.jfr MyApp
// Or via jcmd:
jcmd <pid> JFR.start duration=60s filename=rec.jfr

Lekken verhelpen: checklist

Controleer: statische collecties, niet-geregistreerde luisteraars, ThreadLocals in pools, lekken van verbindingen/streams (gebruik try-with-resources), verwijzingen vanuit inner klassen naar buitenliggende objecten en caches zonder verwijdering.

Snelle controle

Welke JVM-vlag maakt automatisch een heapdump wanneer OutOfMemoryError wordt gegenereerd?

Samenvatting

Veelvoorkomende bronnen van Java-lekken zijn statische collecties, niet-geregistreerde luisteraars, ThreadLocals in pools en caches zonder bovengrens. Spoor ze op met heapdumps en MAT. Verhelp ze met WeakReferences, structuren met een begrensde omvang en door verwijzingen altijd te verwijderen wanneer je ze niet meer nodig hebt.

Gratis beginnen

Leer Java met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
104
Lessen
374

Veelgestelde vragen

Is de les “Geheugenlekken detecteren en verhelpen” gratis?

Ja — de volledige tekst van “Geheugenlekken detecteren en verhelpen” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Java Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Java Academy bevat in totaal 4 lessen.

Wat leer ik in “Geheugenlekken detecteren en verhelpen”?

Identificeer veelvoorkomende patronen van geheugenlekken (statische collecties, listeners, caches) en verhelp ze. Je oefent met Java Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Java Academy te beginnen?

Ervaring vooraf is niet nodig. Java Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “Geheugenlekken detecteren en verhelpen”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Java Academy?

Ja. Elke les over Java Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. JVM-heapregio's en de levenscyclus van objecten
  2. GC-algoritmen: Serial, G1, ZGC, Shenandoah
  3. Geheugenlekken detecteren en verhelpen
  4. GC-tuningflags en JVisualVM-profilering
← Terug naar Java Academy