Follow-up to #37111 / #37112.
#37112 closed the largest part of the Class-File vs ASM heap gap on Java 24+ (84.5 MB to 16.7 MB in the reproducer). Its description notes that one difference is intentionally left for later:
ClassFileMethodMetadata holds AccessFlags and MethodTypeDesc objects and ClassFileAnnotationMetadata one AccessFlags, where SimpleMethodMetadata and SimpleAnnotationMetadata keep plain int and String values instead. [...] Once both are changed, the reproducer matches the ASM baseline of 12.3 MB and the test context mentioned above comes to 46.9 MB.
I'd like to finish that remaining part, but only if it's wanted.
Proposal
Store the same primitives the ASM implementations already keep, in the Class-File implementations:
ClassFileMethodMetadata: int access + String descriptor (instead of AccessFlags + MethodTypeDesc)
ClassFileAnnotationMetadata: int access (instead of AccessFlags)
Flag checks use java.lang.reflect.AccessFlag masks ((access & flag.mask()) != 0); toString() reconstructs a MethodTypeDesc from the stored descriptor only while building the string. Parameter type rendering from #36919 is preserved.
Not ASM
This deliberately avoids the reason #36978 was declined: it introduces no dependency on org.springframework.asm in the Class-File path. The only class-file imports used are java.lang.classfile.* and java.lang.reflect.AccessFlag.
Expected effect
From the reproducer numbers in #37112 (Temurin 25, spring-core 7.0.8):
|
retained heap |
SimpleMetadataReaderFactory (ASM baseline) |
12.3 MB |
ClassFileMetadataReaderFactory, current main (after #37112) |
16.7 MB |
ClassFileMetadataReaderFactory, with this change |
12.3 MB (projected in #37112) |
I validated the change structurally rather than re-running the full heap reproducer: on JDK 25 the spring-core test (ASM) and java24Test (Class-File, via the multi-release JAR) source sets are both green for the classreading and metadata tests, including the existing verifyToString / equals / hashCode contracts and a new java24Test asserting the fields are now primitives. Happy to run the reproducer for an independent figure if useful.
If you'd welcome this, I have a branch ready and can open a PR.
Follow-up to #37111 / #37112.
#37112 closed the largest part of the Class-File vs ASM heap gap on Java 24+ (84.5 MB to 16.7 MB in the reproducer). Its description notes that one difference is intentionally left for later:
I'd like to finish that remaining part, but only if it's wanted.
Proposal
Store the same primitives the ASM implementations already keep, in the Class-File implementations:
ClassFileMethodMetadata:int access+String descriptor(instead ofAccessFlags+MethodTypeDesc)ClassFileAnnotationMetadata:int access(instead ofAccessFlags)Flag checks use
java.lang.reflect.AccessFlagmasks ((access & flag.mask()) != 0);toString()reconstructs aMethodTypeDescfrom the stored descriptor only while building the string. Parameter type rendering from #36919 is preserved.Not ASM
This deliberately avoids the reason #36978 was declined: it introduces no dependency on
org.springframework.asmin the Class-File path. The only class-file imports used arejava.lang.classfile.*andjava.lang.reflect.AccessFlag.Expected effect
From the reproducer numbers in #37112 (Temurin 25, spring-core 7.0.8):
SimpleMetadataReaderFactory(ASM baseline)ClassFileMetadataReaderFactory, currentmain(after #37112)ClassFileMetadataReaderFactory, with this changeI validated the change structurally rather than re-running the full heap reproducer: on JDK 25 the
spring-coretest(ASM) andjava24Test(Class-File, via the multi-release JAR) source sets are both green for theclassreadingand metadata tests, including the existingverifyToString/ equals / hashCode contracts and a newjava24Testasserting the fields are now primitives. Happy to run the reproducer for an independent figure if useful.If you'd welcome this, I have a branch ready and can open a PR.