Skip to content

Fix unresolved sticky class GC roots#9486

Open
wilx wants to merge 1 commit into
apache:masterfrom
wilx:issue-6357
Open

Fix unresolved sticky class GC roots#9486
wilx wants to merge 1 commit into
apache:masterfrom
wilx:issue-6357

Conversation

@wilx

@wilx wilx commented Jul 5, 2026

Copy link
Copy Markdown

Fixes #6357.

ROOT_STICKY_CLASS roots can refer to class object ids that are known from LOAD_CLASS records but are not represented as resolvable Instances by this parser. In the attached issue dump, the failing sticky-class roots are known loaded classes, but GCRoot.getInstance() returns null for them.

LOAD_CLASS records describe classes loaded by the VM: they provide the class object id and class name metadata. They do not by themselves provide the full heap object data that NetBeans uses to construct an Instance; that comes from matching heap dump records such as CLASS_DUMP. When a sticky-class root points at a LOAD_CLASS id without a matching resolvable instance entry, the parser can identify the loaded class metadata but cannot return an Instance, so the result is null.

HprofGCRoots.getGCRoot(Long) assumed every parsed GC root has a non-null Instance when building its instance lookup map. That made retained-size computation fail with a NullPointerException before it could finish walking nearest GC roots.

This change makes the GC-root lookup tolerate those unresolved roots. I also added a small synthetic HPROF regression that writes an unresolved sticky class root and verifies GC-root lookup handles it.

Validation performed:

  • Reproduced the original NPE with the dump from issue NPE when parsing STICKY_CLASS tags in hprof heap dump #6357 before the fix.
  • Verified the same getBiggestObjectsByRetainedSize(15) reproducer succeeds with the fixed profiler jar.
  • Ran HeapSegmentTest: OK (3 tests).
  • Ran broader heap unit classes; only the existing testHeapDumpLog golden-file assertions failed due to JVM system property output differences, unrelated to this change.

Assisted-by: OpenAI GPT-5 Codex


^Add meaningful description above

Click to collapse/expand PR instructions

By opening a pull request you confirm that, unless explicitly stated otherwise, the changes -

  • are all your own work, and you have the right to contribute them.
  • are contributed solely under the terms and conditions of the Apache License 2.0 (see section 5 of the license for more information).

LLMs, Commit messages and PR description:

  • Please make sure (eg. git log) that all commits have a valid name and email address for you in the Author field.
  • LLM assisted commits should be attributed with an Assisted-by: MODEL_NAME MODEL_VERSION line appended to the commit message.
    • Please mention coding assistance in the PR description too (eg. by adding the same Assisted-by line from above)
    • Please describe the changes in your own words - we'd like to know you understand the changes being made!

If you're a first time contributor, see the Contributing guidelines for more information.

If you're a committer, please label the PR before pressing "Create pull request" so that the right test jobs can run.

PR approval and merge checklist:

  1. Was this PR correctly labeled, did the right tests run? When did they run?
  2. Is this PR squashed?
  3. Are author name / email address correct? Are co-authors correctly listed? Do the commit messages need updates?
  4. Does the PR title and description still fit after the Nth iteration? Is the description sufficient to appear in the release notes?

If this PR targets the delivery branch: don't merge. (full wiki article)

Assisted-by: OpenAI GPT-5 Codex
@wilx wilx marked this pull request as ready for review July 5, 2026 10:45
@mbien mbien added Java [ci] enable extra Java tests (java.completion, java.source.base, java.hints, refactoring.java, form) profiler ci:dev-build [ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page) labels Jul 5, 2026
@wilx

wilx commented Jul 6, 2026

Copy link
Copy Markdown
Author

I dug further into this, and this PR is only a stopgap. It prevents the crash, but it does not solve the underlying modeling issue.

ROOT_STICKY_CLASS roots point at class objects / CLASS_DUMP IDs, not ordinary INSTANCE_DUMP records. The current lookup path tries to resolve every GC root through the normal instance index, so these roots can resolve to null. This patch avoids dereferencing that null, but it also means those sticky-class roots are not represented in the Instance -> GCRoot lookup.

A fuller fix would probably need to resolve sticky-class roots through the class-dump model, e.g. to a ClassDumpInstance, and make sure nearest-GC-root / retained-size traversal can use those class objects as roots. Without that, static-field reachability rooted only through sticky classes may still be underrepresented, even though the heap dump itself is parsed.

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

Labels

ci:dev-build [ci] produce a dev-build zip artifact (7 days expiration, see link on workflow summary page) 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

2 participants