RFR: 8350938: ResourceParsingClassHierarchyResolver inflates all Utf8 CP entries
Chen Liang
liach at openjdk.org
Tue Nov 25 04:34:10 UTC 2025
On Fri, 21 Nov 2025 16:54:48 GMT, Trevor Bond <duke at openjdk.org> wrote:
> Enhance `ResourceParsingClassHierarchyResolver.getClassInfo` to use `ClassReaderImpl` to improve performance. Previously this method inflated and stored all UTF-8 entries in the constant pool and later accessed the array of strings to try finding the name of the superclass. `ClassReaderImpl` instead stores constant pool offsets and later lazily reads/inflates UTF8 entries as needed.
>
> I’ve ran all tier 1 tests and tests within `test/jdk/jdk/classfile` on the latest version of this change, and they all pass.
>
> I ran some informal performance testing to see if these changes led to any improvement. I created a .class file with several thousand unique strings in a String array to deliberately enlarge the number of UTF-8 entries in the constant pool. I then benchmarked the performance of running a process nearly identical to `ClassHierarchyInfoTest.testClassLoaderParsingResolver` on this custom class over 200 runs using JMH. The results are as follows.
>
> | Version | Avg Time (ns/op) | Δ vs Before |
> |--------|------------------:|-------------|
> | **Before** | 1,483,671.539 ± 3,477.744 | — |
> | **After** | 1,380,064.517 ± 3,482.434 | ≈ 7.0% faster |
Looks good in principle. Even though people wonder about the buffering policy, I think it is negligible considering that we have caching mechanism. And the constant pool is flexible sized, so "only read the classfile header" might be an optimisitic assumption.
Also, the key to this patch is not performance - it is about the maintainability from a consistent way to parse class files, so in the future, we don't need to update this site any more if we have new constant pool entry type or other format expansions.
src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java line 171:
> 169: if (ci == null) return null;
> 170: try (ci) {
> 171: ClassReader reader = new ClassReaderImpl(ci.readAllBytes(), (ClassFileImpl) ClassFile.of());
Suggestion:
var reader = new ClassReaderImpl(ci.readAllBytes(), ClassFileImpl.DEFAULT_CONTEXT);
And you can remove the 3 imports you have added.
-------------
Marked as reviewed by liach (Reviewer).
PR Review: https://git.openjdk.org/jdk/pull/28458#pullrequestreview-3503212041
PR Comment: https://git.openjdk.org/jdk/pull/28458#issuecomment-3573741129
PR Review Comment: https://git.openjdk.org/jdk/pull/28458#discussion_r2558503313
More information about the core-libs-dev
mailing list