A Spring Boot application with 24 intentional memory leak examples for training purposes. Each leak demonstrates a real-world pattern.
cd ~/workspace/java-memory
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Xmx500m"
# App starts at http://localhost:8080Requires: Java 21+, Maven 3.8+
# Find PID
jps -l | grep MemoryApp
# Dump heap
jmap -dump:format=b,file=heap.hprof <PID>Each leak has an HTTP endpoint (GET /leakN). Some require multiple calls, some require concurrent calls, some sleep 30s to give time for a heap dump.
Quick reference:
- Single call + dump during sleep: leak1, leak2 (30s sleep), leak10
- Multiple sequential calls: leak3 (50+), leak4, leak11 (300+), leak12
- Concurrent calls needed: leak5 (10 threads), leak6 (30 calls), leak8 (2 endpoints simultaneously), leak17
- Special: leak13 (call /persist first, then /export), leak14 (upload plugin), leak20 (POST XML)
Located in mat-mcp/. See mat-mcp/README.md for setup.
# First build (one time)
cd mat-mcp && mvn verify -Pmcp
# Launch as MCP server
./mat-mcp/launch-mat-mcp.shsrc/main/java/victor/training/performance/
leak/ # All leak examples (Leak0 through Leak29)
leak/obj/ # Helper objects (Big20MB, Big1KB, Big100MB, Big)
util/ # Utilities (PerformanceUtil.sleepSeconds, etc.)
mat-mcp/ # Eclipse MAT MCP server for AI-driven analysis
When analyzing a heap dump, follow this workflow:
open_heap_dump- open the .hprofdominator_tree- find biggest memory retainershistogram- find classes with suspicious instance countspath_to_gc_roots- trace why objects can't be GC'dthread_overview- check thread-level memory distributionoql- run targeted queries for deeper investigation