Openj9: Proxy ROMClasses are not stored in the Java 11 shared cache

Created on 5 Mar 2019  路  23Comments  路  Source: eclipse/openj9

Noticed that the Proxy ROMClasses are able to be stored in Java 8 SCC shown as below but not in Java 11 SCC, while running Liberty with Java 11 and Java 8,. Should they also be able to be stored in Java 11?

Java 8

j9shr.1440     > API j9shr_classStoreTransaction_start : enter (classloader=0xe813f298 cpEntries=0x0 cpEntryCount=0 entryIndex=4294967295 loadType=1 partition=0x0 classname=com/sun/proxy/$Proxy3 ismodified=0 takeReadWriteLock=1)
...
j9shr.1521     - CM commitOrphanROMClass : Data was stored in the cache for J9ROMClass com/sun/proxy/$Proxy3 at address 0xa32b1820
...
j9shr.1465     - API j9shr_classStoreTransaction_stop : New data has been stored to the cache for class com/sun/proxy/$Proxy3 (ROMClass address 0xa32b1820).
(AOT cold) Compiling com/sun/proxy/$Proxy3.traceGroups()[Ljava/lang/String;  OrdinaryMethod j9m=00000000025B54C0 t=58417 compThread=0 memLimit=262144 KB freePhysicalMemory=237906 MB isRomClassForMethodInSharedCache=1



md5-9b0da4df020f9dda871b1579aca37e50



(cold) Compiling com/sun/proxy/$Proxy3.traceGroups()[Ljava/lang/String;  OrdinaryMethod j9m=0000000001C4A2D0 t=61653 compThread=1 memLimit=262144 KB freePhysicalMemory=237975 MB isRomClassForMethodInSharedCache=0
vm externals jdk11 jdk12

All 23 comments

@a7ehuo Do you know which API is used to generate the proxy classes? Is it Unsafe.defineClass or Unsafe.defineAnonymousClass?

The ROM classes will be tagged with an Unsafe bit if they came from Unsafe.defineClass.

fyi @hangshao0 @pshipton

It is stored as orphan in Java 8, which means even it is stored, it won't be used.

@hangshao0 it won't be loaded directly, but the shared class will be used if the rom class is the same from run to run.

and if the rom class is used, there can be AOT which is used as well.

Do you have a test case ? @a7ehuo

@hangshao0 The ROMClass is used. On the above example, because the ROMClass is stored in Java 8 SCC, its method is able to be AOT compiled in the first run and be AOT loaded in the subsequent runs. In Java 11, no traces on storing the ROMClass, JIT compilation is chosen and has to do JIT compilation on the method in all the subsequent runs.

@hangshao0 I ran Liberty with AdoptOpenJDK8+OpenJ9 0.12.1 and AdoptOpenJDK11+OpenJ9 0.12.1.

In Java 11, isClassUnsafe() returns true for this class, so it is not shared.

https://github.com/eclipse/openj9/blob/d61205ddaeda88de034fcba86b63fcc0590bca5b/runtime/bcutil/ROMClassCreationContext.hpp#L254-L276

@hangshao0 Thanks for the update Hang. Do we understand why Proxy class is unsafe in Java 11 but safe in Java 8?

I expect it has to do with the internal API used to define the classes. We should be looking at how to fix the check so that Proxy classes can continue to be shared.

FYI https://github.com/eclipse/openj9/pull/4919 which is changing some of the class definition code.

Fixing this won't make the 0.14 release.

Moving out as it won't make 0.15

@a7ehuo Do you know which API is used to generate the proxy classes? Is it Unsafe.defineClass or Unsafe.defineAnonymousClass?

The ROM classes will be tagged with an Unsafe bit if they came from Unsafe.defineClass.

In JDK8 proxy classes are defined using defineClass0, however in JDK11 they are defined using UNSAFE.defineClass

https://github.com/ibmruntimes/openj9-openjdk-jdk8/blob/46e5e62038e4ad1f3b3d7debebaf5d5d594f9934/jdk/src/share/classes/java/lang/reflect/Proxy.java#L642

https://github.com/ibmruntimes/openj9-openjdk-jdk11/blob/965d0c0df359f3da224b865701bbcc044b7104c2/src/java.base/share/classes/java/lang/reflect/Proxy.java#L538

We removed the Unsafe.defineClass in Java 11 and used defineClass0 as in Java 8 and it seems like it is working. I am able to see the $Proxy0 class in the SCC as an orphan.

I'm working on adding a new command line option to store Unsafe classes:
-XX:[+/-]ShareUnsafeClasses

This command line option when combined with -XX:[+/-]ShareAnonymousClasses will have 4 different behaviours:

  1. -XX:+ShareAnonymousClasses -XX:+ShareUnsafeClasses, this will share all unsafe classes
  2. -XX:+ShareAnonymousClasses -XX:-ShareUnsafeClasses, this will only share anonymous classes and not other unsafe classes
  3. -XX:-ShareAnonymousClasses -XX:+ShareUnsafeClasses, this will only share unsafe classes that are not anonymous
  4. -XX:-ShareAnonymousClasses -XX:-ShareUnsafeClasses, this will share neither.

The current default behaviour for -XX:[+/-]ShareAnonymousClasses is the + option.

Also I am not sure if we want to have the 3rd option. It might be a little confusing for the user since we are sharing unsafe classes but not anonymous classes which are also unsafe.

These options aren't intended for end users. They're needed for two reasons:

  1. Serviceability - to allow the enabling / disabling storing these classes if we expect a problem in this code.

  2. Testing - to enable tests to validate the storing (or not) of the classes.

Ideally, a user never needs these options as the classes are stored and retrieved without error.

How many unsafe classes are there if you run a real application using -XX:+ShareUnsafeClasse ? @sogutbera

I ran Eclipse multiple times and the difference between the number of classes when running with -XX:-ShareUnsafeClasses and -XX:+ShareUnsafeclasses is always less than 40 classes. So I am assuming there are less than 40 in Eclipse.

Can you try with various other frameworks? Maybe Spring Pet-Clinic, Liberty, JRuby?

Spring Pet-Clinic has ~130 non-lambda unsafe classes, 0 non-lambda anonymous classes, ~740 lambda classes and a total number of ~12280 ROMClasses

Liberty has ~116 non-lambda unsafe classes, and a total number of ~13607 ROMClasses

I ran Jruby both on Mac with Java 11 and Linux with Java8.
On Mac with Java 11, there are ~28 non-anonymous unsafe classes, ~35 anonymous classes, and a total number of ~6541 ROMClasses
On Linux with Java 8, there are 5 lambda classes, 0 non-lambda anonymous classes and ~5000 ROMClasses in total but this number differs by a few hundred from run to run.

I could also get more numbers if it is needed.

Thanks @sogutbera I think those numbers paint a clear enough picture of the risk to adding this option - low compared to the anonymous classes change.

This is the issue you are going to pick up. @doomerxe

Was this page helpful?
0 / 5 - 0 ratings

Related issues

PowerUser1234 picture PowerUser1234  路  3Comments

AdamBrousseau picture AdamBrousseau  路  6Comments

mikezhang1234567890 picture mikezhang1234567890  路  5Comments

dsouzai picture dsouzai  路  5Comments

Jeeppler picture Jeeppler  路  5Comments