RFR: 8268406: Deallocate jmethodID native memory [v11]

Coleen Phillimore coleenp at openjdk.org
Thu Jun 26 18:01:59 UTC 2025


On Thu, 26 Jun 2025 12:20:57 GMT, Coleen Phillimore <coleenp at openjdk.org> wrote:

>> This change uses a ConcurrentHashTable to associate Method* with jmethodID, instead of an indirection.  JNI is deprecated in favor of using Panama to call methods, so I don't think we're concerned about JNI performance going forward.  JVMTI uses a lot of jmethodIDs but there aren't any performance tests for JVMTI, but running vmTestbase/nsk/jvmti with in product build with and without this change had no difference in time.
>> 
>> The purpose of this change is to remove the memory leak when you unload classes: we were leaving the jmethodID memory just in case JVMTI code still had references to that jmethodID and instead of crashing, should get nullptr.  With this change, if JVMTI looks up a jmethodID, we've removed it from the table and will return nullptr.  Redefinition and the InstanceKlass::_jmethod_method_ids is somewhat complicated.  When a method becomes "obsolete" in redefinition, which means that the code in the method is changed, afterward creating a jmethodID from an "obsolete" method will create a new entry in the InstanceKlass table.  This mechanism increases the method_idnum to do this.  In the future maybe we could throw NoSuchMethodError if you try to create a jmethodID out of an obsolete method and remove all this code.  But that's not in this change.
>> 
>> Tested with tier1-4, 5-7.
>
> Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision:
> 
>   More comment grammar fixes, thank you for reading the comments again, Dan!

// This function must only be called when JVM/TI
// CLASS_LOAD events have been enabled since agent startup. The enabled
// event will cause the jmethodIDs to be allocated at class load time.
// The jmethodIDs cannot be allocated in a signal handler because locks
// cannot be grabbed in a signal handler safely.


I do not see any code that creates jmethodIDs for all the methods in a ClassLoad JVMTI event.  ACGCT does call 


trace->frames[count].method_id = method->find_jmethod_id_or_null();


so it won't create jmethodIDs from a signal handler.  Keeping them live for the frames depends on when the native caller of ASGCT uses the trace that is returned.  If the frames are still on the call stack, the methods cannot be unloaded because they're still on the call stack.  If the frames returned by ASGCT are stored somewhere else, and accessed later, they could be null.  I don't see any code that makes this work tbh.  Most methods do not have jmethodIDs.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/25267#issuecomment-3009304966


More information about the hotspot-dev mailing list