All posts

Fix Memory Leak in Java

Diagnose and fix Java memory leaks including classloader leaks, thread-local accumulation, and unclosed resources in production.

Java Memory Leaks

Despite garbage collection, Java applications can leak memory through object references that prevent GC from reclaiming objects. Here are the most common patterns.

Static Collections

The most straightforward leak — a static map that grows forever:

// LEAK
public class UserTracker {
    private static final Map<String, UserSession> sessions = new HashMap<>();

    public static void track(String id, UserSession session) {
        sessions.put(id, session); // Never removed
    }
}

// FIX: Use WeakHashMap or implement cleanup
private static final Map<String, UserSession> sessions =
    Collections.synchronizedMap(new WeakHashMap<>());

Unclosed Resources

// LEAK: connection never closed on exception
public List<User> getUsers() {
    Connection conn = dataSource.getConnection();
    // If this throws, conn is leaked
    return query(conn);
}

// FIX: try-with-resources
public List<User> getUsers() {
    try (Connection conn = dataSource.getConnection()) {
        return query(conn);
    }
}

ThreadLocal Leaks

In servlet containers, threads are pooled and reused:

// LEAK in web apps: ThreadLocal never cleared
private static final ThreadLocal<List<String>> context = new ThreadLocal<>();

// FIX: always clean up in a finally block or filter
try {
    context.set(new ArrayList<>());
    // ... handle request
} finally {
    context.remove();
}

Heap Dump Analysis

jmap -dump:format=b,file=heap.hprof <pid>
# Open in Eclipse MAT or VisualVM

Bugsly captures OutOfMemoryError events with thread dumps and memory statistics, providing the context needed to trace the leak without reproducing it locally.

Try Bugsly Free

AI-powered error tracking that explains your bugs. Set up in 2 minutes, free forever for small projects.

Get Started Free