JDK-8003551 : Move Signers out to the JDK
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • Submitted: 2012-11-16
  • Updated: 2024-10-11
  • Resolved: 2024-07-19
Related Reports
Blocks :  
Blocks :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Description

There's a "signers" field in the VM's InstanceKlass metadata which we simply store for the JDK.   This field is in all of the classes whether they have signers or not.   To save space, CVM moved the signers field out to Java in a WeakHashMap.    We'd like to save space in Hotspot too especially for the cases where large applications load 300K classes.  Can this be done?

Mail from Jiangli Zhou:

"We do handle signer differently in CVM. We moved signer reference into java code and use WeakHeashMap to keep referece of the signers. I remember we discussed with Coleen earlier this year. Following is from you after you looked into the code:

====================================
I looked at the code some more and figured out that the WeakHashMap works the way you would want. Each entry is a weakref to the key (the Class instance), so the entry stays around as long as the key does, and goes away once the key is gc'd. This is what you want. It saves you from having to explicitly remove the key from a regular HashMap when the Class unloads.

I think this would be a good memory optimization to apply. It allows you to get rid of the signers field for each instanceKlass. You just need to make sure it really is rare that setsigners() is ever called. Otherwise you end up using more memory for the WeakHashMap approach. "
Comments
JDK-8334772 added Class.signers as an explicit field and removed the injected field so I think we can close this issue.
19-07-2024

With JVMTI heap functions deprecated, we might be able to purge references to signers from the JVM.
10-11-2021

The idea is to make a weak hashtable with klass,signers because signers aren't generally set individually for each class. Then we wouldn't need a signers field per class (in the instance of java/lang/Class or hidden in the jvm). This was done by another one of our products in embedded space. This change is blocked because it requires a change the jvmti and hprof specifications, but the changes are here. http://cr.openjdk.java.net/~coleenp/8003551_jdk/ http://cr.openjdk.java.net/~coleenp/8003551_hotspot
17-11-2014

Not quite sure what point you are making. ClassLoader.setSigners can be made public by a subclass. It's current implementation is to call Class.setSigners. If you remove that then you need to provide a way for classes to become signed as that is what the API requires. This all started as moving signers from VM data to JDK so not sure why we thought we could get rid of it (and setSigners). ??
07-02-2014

The experimental (and since moved) JVMPI also defined the signers field in its class dump record, this may have partly influenced its inclusion in the JVM TI spec. I wouldn't expect an real issues if it weren't reported to JVM TI agents although it would likely require a note/adjustment in the JVM TI spec.
24-01-2014

Ok, let's change it then. Adding Robert Field for details.
23-01-2014

Agreed, it seems we were reporting them simply because they were there in the instanceKlass. What can JVMTI callers do with signers? If they got null what bad things would happen? Or NoSuchFieldException ?
23-01-2014

http://download.java.net/jdk8/docs/platform/jvmti/jvmti.html#Heap look for "REFERENCE_SIGNERS". Yes, we can always change the spec. A good person for background is Robert Field.
23-01-2014

Well, it's not a bad answer. When looking at this code for the first time in my life I also had the impression this is only done because the values live in the JVM and there is no other way to report them. Where is this spec? Can we change it?
23-01-2014

In JVMTI, the signers are reported during heap traversal (jvmtiTagMap.cpp:iterate_over_class). When a class object is encountered a number of "special" references are reported (because the spec says so): signers, protection domain. super class, etc. This reporting happens at a safepoint, so we can't run Java code there to call getSigners(). We could follow simple references on the heap, but that is not sufficient here. (I believe the reason these "special" references are reported is that since they are stored in the JVM, there is no other way to get them; there are no fields that contain these references that the JVMTI agent can follow. ) Sorry, not the answer you were looking for. There may still be a way, but I can't think of any right now.
23-01-2014

Coleen pointed me to the right thing. I will never understand why JVMTI stuff is generated from XML. [~sla], can we somehow remove signers from the JVM but still make JVMTI happy?
23-01-2014

David, can you get more specific on JVMTI? Where does JVMTI access the signers? I can't find that code in the JVM.
23-01-2014

The fact that JVMTI provides access to the signers recently came to light. That complicates potential changes here.
22-05-2013

It seems there might be a better way to address this than what's proposed above. The information is already there. Simply change the getSigners method to: public Object[] getSigners() { CodeSource cs = getProtectionDomain().getCodeSource(); return (cs == null ? null : cs.getCertificates()); } (there may be some additional optimizations to quickly return null if it is a system class)
04-04-2013

Yes, this is the intention of filing this bug. These performance considerations need to be addressed relative to the footprint savings of having all classes have a pointer to signers that are almost never filled in.
19-11-2012

If the intent is to provide a static WeakHashMap to be shared amongst all Classes then there are likely to be significant performance considerations: - access to the map will require explicit synchronization and so is a potential bottleneck - additional weak references places more strain on GC
18-11-2012

It is not clear to me where the "signers" field will be moved to. If we are simply moving a field from the VM side of a Class to the Java side of a Class then there is no memory saving.
18-11-2012