Skip to content

Fix unresolved sticky class GC roots#9497

Merged
matthiasblaesing merged 1 commit into
apache:masterfrom
wilx:issue-6357-fix
Jul 24, 2026
Merged

Fix unresolved sticky class GC roots#9497
matthiasblaesing merged 1 commit into
apache:masterfrom
wilx:issue-6357-fix

Conversation

@wilx

@wilx wilx commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Fixes #6357.

ROOT_STICKY_CLASS records contain the HPROF object ID of the class object they keep alive. NetBeans already indexes CLASS_DUMP IDs in the heap object map and represents them as ClassDumpInstances, so resolvable sticky-class roots can participate in nearest-GC-root and retained-size traversal, including references held in static fields.

The remaining problem was in HprofGCRoots.getGCRoot(Long). When building its object-ID-to-root lookup, it unnecessarily resolved every root through GCRoot.getInstance() and then recovered the ID from the returned Instance. Some valid root records in the issue dump refer to loaded-class IDs for which the dump contains no corresponding resolvable heap object. getInstance() therefore returns null, and dereferencing it caused the reported NullPointerException.

This change builds the lookup directly from the target object ID stored in each HPROF GC-root record. Resolvable class-object roots continue to be seeded into reachability through the existing idToOffsetMap, so objects reachable only through their static fields remain reachable. Unresolved root records remain available from getGCRoots(), but no synthetic object or references are invented when the dump has no matching heap record.

The internal root collection is now typed as HprofGCRoot, making the raw target-ID invariant compile-time checked rather than relying on a runtime cast. No public API signatures change.

The synthetic HPROF test support now writes static object fields and either resolved or unresolved sticky-class root IDs. Regression coverage verifies both that:

  • a sticky class resolves to a ClassDumpInstance, is found by GC-root lookup, and retains an object referenced only by a static field;
  • an unresolved sticky-class root remains recorded and retained-size computation completes without an exception.

Validation performed:

  • Reproduced the original failure path with the dump from issue NPE when parsing STICKY_CLASS tags in hprof heap dump #6357.
  • Verified the issue dump contains 3,166 sticky-class roots: 2,882 resolve to heap class objects and 284 have no corresponding heap object.
  • Verified getBiggestObjectsByRetainedSize(15) completes successfully on the issue dump.
  • Ran HeapSegmentTest: 4 tests passed.
  • Ran the complete profiler/lib.profiler unit suite with the module access required by its legacy CPU tests: 70 tests ran, 68 passed, and 2 failed.
  • The two remaining failures are the existing testHeapDumpLog golden-file comparisons in HeapTest and HeapFromBufferTest; they contain the same JVM system properties in a different iteration order on this JDK and are unrelated to the GC-root change.

Assisted-by: OpenAI GPT-5 Codex

@wilx
wilx marked this pull request as ready for review July 10, 2026 20:46
@wilx wilx changed the title Issue 6357 fix Fix unresolved sticky class GC roots Jul 11, 2026
@apache apache locked and limited conversation to collaborators Jul 13, 2026
@apache apache unlocked this conversation Jul 13, 2026
@apache apache locked and limited conversation to collaborators Jul 13, 2026
@apache apache unlocked this conversation Jul 13, 2026
@matthiasblaesing matthiasblaesing added the Java [ci] enable extra Java tests (java.completion, java.source.base, java.hints, refactoring.java, form) label Jul 13, 2026
@apache apache locked and limited conversation to collaborators Jul 13, 2026
@apache apache unlocked this conversation Jul 13, 2026
@lkishalmi
lkishalmi requested a review from mbien July 18, 2026 15:32
@matthiasblaesing

Copy link
Copy Markdown
Contributor

In general this makes sense to me. Thank you @wilx.

Is there a reason for two commits (other than to see the evolution of the patch?)? I'm not seeing it right now, so I'd suggest to squash the two commits.

@matthiasblaesing matthiasblaesing added this to the NB32 milestone Jul 19, 2026
@wilx

wilx commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

In general this makes sense to me. Thank you @wilx.

Is there a reason for two commits (other than to see the evolution of the patch?)? I'm not seeing it right now, so I'd suggest to squash the two commits.

No. I started with just mitigating the NPE and then tried an actual fix.

@wilx
wilx force-pushed the issue-6357-fix branch from 66beb5d to 092044f Compare July 19, 2026 18:15
@wilx

wilx commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

Squashed.

@mbien

mbien commented Jul 19, 2026

Copy link
Copy Markdown
Member

not a showstopper but I noticed that the module isn't hooked into CI atm. We should consider to do that first (can be separate PR). We might have to check which tests run reliably and/or are worth running and setup the test config for the module - given that those didn't run in ages.

@wilx
wilx force-pushed the issue-6357-fix branch 2 times, most recently from 54b6b01 to 94b5d48 Compare July 22, 2026 17:28
@apache apache locked and limited conversation to collaborators Jul 23, 2026
@apache apache unlocked this conversation Jul 23, 2026
Assisted-by: OpenAI GPT-5 Codex
@wilx
wilx force-pushed the issue-6357-fix branch from 94b5d48 to e5f2314 Compare July 24, 2026 14:52
@matthiasblaesing
matthiasblaesing merged commit 3a1f607 into apache:master Jul 24, 2026
71 of 73 checks passed
@matthiasblaesing

Copy link
Copy Markdown
Contributor

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Java [ci] enable extra Java tests (java.completion, java.source.base, java.hints, refactoring.java, form) profiler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NPE when parsing STICKY_CLASS tags in hprof heap dump

3 participants