Java Academy · Lektion

Upptäck och åtgärda minnesläckor

Identifiera vanliga mönster för minnesläckor (statiska samlingar, lyssnare, cachar) och åtgärda dem.

Lektion 3 av 413 steg

Upptäck och åtgärda minnesläckor är en gratis lektion i Java Academy på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Java Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Java Academy innehåller totalt 4 lektioner.

Vad är en minnesläcka i Java?

En minnesläcka i Java uppstår när objekt inte längre behövs men fortfarande är starkt nåbara, vilket hindrar GC från att återta minnet. Heapen växer tills ett OutOfMemoryError kastas.

Ackumulering i statiska samlingar

Ett statiskt fält som innehåller en växande samling är en klassisk läcka. Objekt som läggs till men aldrig tas bort förblir levande så länge applikationen körs.

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
}

Oregistrerade händelselyssnare

Om en lyssnare registreras utan att någonsin tas bort hålls både lyssnaren och alla objekt som den refererar till levande. Avregistrera alltid lyssnare när de inte längre behövs.

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

ThreadLocal-variabler som inte rensas

I trådpooler överlever ThreadLocal-värden mellan uppgifter eftersom trådarna återanvänds. Om värdet inte rensas läcker en uppgifts data in i efterföljande uppgifter på samma tråd.

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
}

Classloader-läckor i varmdeployerade applikationer

I servletcontainrar använder varje distribution en ny classloader. Om någon klass håller en statisk referens till en klass från den gamla classloadern kan hela den gamla classloadern, och alla dess klasser, inte samlas in av GC.

Identifiera minnesläckor med heap-dumpar

Ta en heap-dump med jmap -dump:format=b,file=heap.hprof <pid> och öppna den sedan i Eclipse MAT eller VisualVM för att hitta de största objekten efter behållen minnesmängd och deras GC-rötter.

// 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)

MAT:s rapport "Leak Suspects" identifierar automatiskt objekt med stor behållen heap och visar sökvägen från GC-rötterna. Börja med vyn "Dominator Tree" för att hitta de största problemen.

Undvik läckor med WeakReference

Omslut cachade objekt eller lyssnarobjekt i WeakReference. GC kan återta dem vid minnesbrist. Kontrollera alltid om resultatet från get() är 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

Begränsade cachar med LinkedHashMap LRU

Åsidosätt removeEldestEntry i en LinkedHashMap för att begränsa cachens storlek och automatiskt ta bort den post som inte har använts på längst tid.

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
    }
};

Profilera allokeringar med Java Flight Recorder

JFR (Java Flight Recorder) samlar in allokeringsprofiler med minimal overhead. Aktivera det med -XX:StartFlightRecording och analysera resultatet med 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

Åtgärda läckor: checklista

Kontrollera: statiska samlingar, oregistrerade lyssnare, ThreadLocals i pooler, läckor från anslutningar och strömmar (använd try-with-resources), referenser från inre klasser till yttre objekt samt cachar utan automatisk borttagning.

Snabbkontroll

Vilken JVM-flagga dumpar automatiskt heapen när OutOfMemoryError kastas?

Sammanfattning

Vanliga källor till Java-läckor är statiska samlingar, oregistrerade lyssnare, ThreadLocals i pooler och obegränsade cachar. Identifiera dem med heap-dumpar och MAT. Åtgärda dem med WeakReferences, begränsade datastrukturer och genom att alltid ta bort referenser när de inte längre behövs.

Gratis att börja

Lär dig Java med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
104
Lektioner
374

Vanliga frågor

Är lektionen ”Upptäck och åtgärda minnesläckor” gratis?

Ja – hela texten till ”Upptäck och åtgärda minnesläckor” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Java Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Java Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Upptäck och åtgärda minnesläckor”?

Identifiera vanliga mönster för minnesläckor (statiska samlingar, lyssnare, cachar) och åtgärda dem. Ni övar på Java Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Java Academy?

Du behöver inga förkunskaper. Utbildningen i Java Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Upptäck och åtgärda minnesläckor”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Java Academy-lektionen?

Ja. Varje Java Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. JVM:s heapregioner och objektens livscykel
  2. GC-algoritmer: Serial, G1, ZGC, Shenandoah
  3. Upptäck och åtgärda minnesläckor
  4. GC-flaggor och profilering med JVisualVM
← Tillbaka till Java Academy