Memory Leaks and Profiling
Common retention sources include unbounded maps, static collections, caches without eviction, listener registrations, thread locals, and accidentally retained object graphs.
static final Map<String, byte[]> cache = new HashMap<>();
void add(String id, byte[] data) {
cache.put(id, data);
}
A heap dump reveals retained memory. Allocation profiling identifies where objects are created rapidly. GC logs and JFR show collection behavior and allocation pressure.
Ask: What is growing? Which objects are retained? Who retains them? Is the growth expected? What is the live set after GC?
Key Takeaways
- Look at retained size and reference paths, not only object counts.
- Heap dumps answer retention questions; allocation profiling answers creation-rate questions.
- Caches need lifecycle or eviction policies.