JDK-8338526 : Don't store abstract and interface Klasses in class metaspace
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2024-08-16
  • Updated: 2025-08-19
  • Resolved: 2024-09-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 24
24 b15Fixed
Related Reports
Causes :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Abstract and interface classes can never have an instance, so their compressed representation is never used.  These classes can be stored in the non-class metaspace, to save space for encoding more classes in the class metaspace.

Also these lambdaform classes: java/lang/invoke/LambdaForm$MH are generated only to provide a static function.  They're marked ACC_FINAL but if marked with ACC_ABSTRACT, they also can be added to non-class metaspace.  Unfortunately, ACC_FINAL and ACC_ABSTRACT cannot be used together because it doesn't make sense, but we need some way to say that these classes are not used for creating instances.


Comments
I'm a bit concerned about this one. I'm working on megamorphic dispatch, and a uniform representation of compressed class pointers allows me to squeeze klass+offset into a single 64-bit word. This in turn allows fast and simple method lookups. I need, at least, to be able to use compressed interface pointers. If interfaces are "somewhere else", and thus incompressible, I can't do what I need to do. If, however, klass and non-klass metaspaces are contiguous I guess it'd be OK, if not ideal. I'd much rather use compressed klass pointers without having to decode them.
07-10-2024

It's not fixed by JDK-8340184. I've filed JDK-8340274 and copied the comments.
17-09-2024

I took a look at the test but did not really understand what is going wrong here. Someone will have to analyze on AIX. We move interface classes from class metaspace to non-class metaspace. But the total Metaspace usage should not change (much, modulo tiny alignment effects). The test runs with -XX:+MaxMetaspaceSize. That size is a threshold for the sum of class and non-class metaspace. It should not matter much whether we now use more non-class metaspace at the expense of less class space, the sum should be nearly identical. I also don't get what AIX has to do with this, but remember Andreas Steiner asking me not long ago why AIX metaspace usage is higher than other platforms. No idea why, unless ppc JIT needs more memory for things like methodcounters? That is the only thing I could think of that could bring per-platform differences.
16-09-2024

I don't know if JDK-8340184 will fix it. The test is trying to fill class metaspace with interface classes, which is harder for it to do. It should probably be fixed to not use an interface class. Also I had to change the test to not get OOME for metaspace for String concat classes that were wrapped in BootstrapMethodError.
16-09-2024

I think this will be fixed by JDK-8340184.
16-09-2024

Since at least 11th September we see the test vmTestbase/metaspace/shrink_grow/ShrinkGrowMultiJVM/ShrinkGrowMultiJVM.java fail on AIX. Exception/error message is metaspace.shrink_grow.ShrinkGrowTest.ShrinkGrowTest$TestFault: %jvm#2%We haven't cleaned metaspace yet! at metaspace.shrink_grow.ShrinkGrowTest.ShrinkGrowTest.throwFault(ShrinkGrowTest.java:105) at metaspace.shrink_grow.ShrinkGrowTest.ShrinkGrowTest.go(ShrinkGrowTest.java:150) at metaspace.shrink_grow.ShrinkGrowTest.ShrinkGrowTest.run(ShrinkGrowTest.java:125) at metaspace.shrink_grow.ShrinkGrowTest.ShrinkGrowTest.main(ShrinkGrowTest.java:82) Exception in thread "main" metaspace.shrink_grow.ShrinkGrowTest.ShrinkGrowTest$TestFault: %jvm#2%We haven't cleaned metaspace yet! at metaspace.shrink_grow.ShrinkGrowTest.ShrinkGrowTest.throwFault(ShrinkGrowTest.java:105) at metaspace.shrink_grow.ShrinkGrowTest.ShrinkGrowTest.go(ShrinkGrowTest.java:150) at metaspace.shrink_grow.ShrinkGrowTest.ShrinkGrowTest.run(ShrinkGrowTest.java:125) at metaspace.shrink_grow.ShrinkGrowTest.ShrinkGrowTest.main(ShrinkGrowTest.java:82) %jvm#2%failed :%jvm#2%We haven't cleaned metaspace yet! Could this be related to JDK-8338526 ?
16-09-2024

Changeset: ad104932 Branch: master Author: Coleen Phillimore <coleenp@openjdk.org> Date: 2024-09-10 11:43:21 +0000 URL: https://git.openjdk.org/jdk/commit/ad104932e6c26806c353ad048ce5cff7d2b4c29a
10-09-2024

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/19157 Date: 2024-05-09 13:51:09 +0000
21-08-2024