1. Choose the question and artifact
A memory incident can require different answers: when the application was paused, which objects grew, or which memory category is pressuring the process. GC logs help reconstruct collection activity; heap dumps show objects and references according to format; javacores provide JVM context, threads, and useful summaries. No artifact replaces all the others. Confirm product, JVM, and version before choosing tools. Current OpenJ9 documentation supports diagnostic concepts here without claiming every recent option exists in the IBM Java used by a traditional installation. Plan collection, space, and file access because diagnostics can contain application data.
2. Measure pauses without duplicating events
A GC cycle can contain phases and, depending on policy, work concurrent with the application. Adding cycle duration to its internal phases counts time twice. In the exercise, the inputs are already classified, complete, nonoverlapping exclusive intervals from the same JVM. If they total 4.8 seconds within sixty seconds, they represent eight percent of the window. That value is neither CPU percentage nor a latency percentile. To assess impact, align pause periods with request and workload timelines. One long pause and several short pauses can have the same sum but different consequences for response-time objectives.
3. Distinguish growth from unintended retention
After comparable global collections, occupancy is observed at 2.1, 2.3, and 2.2 GiB. These three values do not demonstrate a leak. One cache may warm up and stabilize; another may retain references beyond the intended lifetime. Investigation needs knowledge of limits, expiry, and workload volume. Analyze a sufficiently long trend and dominant objects with the development team. Even when growth exists, the problem can be insufficient capacity for legitimately required data. Support’s role is to present hypotheses and evidence, including what remains unmeasured. Avoid converting any post-GC value into an automatic classification of leakage or perfect health.
4. Understand own size and retained memory
Shallow heap represents the object’s own size; retained heap relates to the set that would become unreachable if that object became unreachable. In a synthetic graph, a root reaches A with ten bytes, and only A reaches B with ninety bytes. A has shallow size ten and retained size one hundred. If a path also exists directly from the root to B, removing A leaves B reachable and A’s retained size becomes ten. This model teaches reachability rather than real Java object layout. In MAT analysis, distinguish dominance from direct reference and confirm what the format exposes; some dumps lack complete root information.
5. Read memory breakdowns and limits
In a synthetic hierarchical summary, VM=300 MiB contains Heap=200, Threads=60, and Other=40. The branch represents three hundred rather than six hundred MiB: the parent already contains its children. NATIVEMEMINFO reports categories of virtual allocations known to the JVM and should not be treated as a complete RSS measurement. Confirm whether the operating-system tool reports virtual or resident memory and which allocations are covered. Xmx limits Java heap rather than the whole process. Stacks, JIT, and libraries also need headroom. Increasing heap to address every memory error can worsen pressure outside it. Analysis should relate categories, limits, and workload evolution.
6. Compare captures and communicate the hypothesis
Object addresses can change during GC, even across dumps from the same process. To compare evolution, use aggregates by class and context, retained sets, and histograms, considering class loader, collection phase, and request mix. An increase in count does not automatically identify which concrete objects persisted. Record workload differences before attributing growth to a code change. At an incident meeting, present the observation, hypothesis, next experiment, and evidence that would weaken it. This lesson’s activities use fictional graphs and numbers. No real heap dump was generated and no leak correction was demonstrated in a WebSphere installation.
SYNTHETIC EVIDENCE / DADOS SINTÉTICOS
window_ms = 60000
exclusive_pause_ms = [1200, 1200, 2400]
pause_fraction = 4800 / 60000 = 0.08
root -> A(10 bytes) -> B(90 bytes)
retained(A) = 100 bytes
additional edge: root -> B
retained(A) = 10 bytesTeaching graph: root → A(10) → B(90). Removing A makes one hundred bytes unreachable. With an additional root → B edge, removing A releases only A’s ten bytes in the model.
Common pitfalls
Adding parents and children, confusing cycle duration with pause time, treating addresses as persistent identities, or considering Xmx a whole-memory limit.
Related topics: Javacore and heap dump · GC and response time · Reachability and dominators
Choose evidence according to memory type and hypothesis; calculate without duplication and distinguish observed retention from functional need.
Reference: Verbose garbage collection logs · DR WebSphere traditional ND 9.0.5; maintenance baseline 9.0.5.29 (2026-09-08); documentation reviewed 2026-09-30