mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 17:44:40 +02:00
8268364: jmethod clearing should be done during unloading
Reviewed-by: dcubed, eosterlund
This commit is contained in:
parent
53ad903a82
commit
3d84398d12
2 changed files with 23 additions and 16 deletions
|
@ -550,6 +550,21 @@ void ClassLoaderData::unload() {
|
|||
// after erroneous classes are released.
|
||||
classes_do(InstanceKlass::unload_class);
|
||||
|
||||
// Method::clear_jmethod_ids only sets the jmethod_ids to NULL without
|
||||
// releasing the memory for related JNIMethodBlocks and JNIMethodBlockNodes.
|
||||
// This is done intentionally because native code (e.g. JVMTI agent) holding
|
||||
// jmethod_ids may access them after the associated classes and class loader
|
||||
// are unloaded. The Java Native Interface Specification says "method ID
|
||||
// does not prevent the VM from unloading the class from which the ID has
|
||||
// been derived. After the class is unloaded, the method or field ID becomes
|
||||
// invalid". In real world usages, the native code may rely on jmethod_ids
|
||||
// being NULL after class unloading. Hence, it is unsafe to free the memory
|
||||
// from the VM side without knowing when native code is going to stop using
|
||||
// them.
|
||||
if (_jmethod_ids != NULL) {
|
||||
Method::clear_jmethod_ids(this);
|
||||
}
|
||||
|
||||
// Clean up global class iterator for compiler
|
||||
ClassLoaderDataGraph::adjust_saved_class(this);
|
||||
}
|
||||
|
@ -694,20 +709,7 @@ ClassLoaderData::~ClassLoaderData() {
|
|||
_metaspace = NULL;
|
||||
delete m;
|
||||
}
|
||||
// Method::clear_jmethod_ids only sets the jmethod_ids to NULL without
|
||||
// releasing the memory for related JNIMethodBlocks and JNIMethodBlockNodes.
|
||||
// This is done intentionally because native code (e.g. JVMTI agent) holding
|
||||
// jmethod_ids may access them after the associated classes and class loader
|
||||
// are unloaded. The Java Native Interface Specification says "method ID
|
||||
// does not prevent the VM from unloading the class from which the ID has
|
||||
// been derived. After the class is unloaded, the method or field ID becomes
|
||||
// invalid". In real world usages, the native code may rely on jmethod_ids
|
||||
// being NULL after class unloading. Hence, it is unsafe to free the memory
|
||||
// from the VM side without knowing when native code is going to stop using
|
||||
// them.
|
||||
if (_jmethod_ids != NULL) {
|
||||
Method::clear_jmethod_ids(this);
|
||||
}
|
||||
|
||||
// Delete lock
|
||||
delete _metaspace_lock;
|
||||
|
||||
|
|
|
@ -2254,10 +2254,15 @@ bool Method::is_method_id(jmethodID mid) {
|
|||
Method* Method::checked_resolve_jmethod_id(jmethodID mid) {
|
||||
if (mid == NULL) return NULL;
|
||||
Method* o = resolve_jmethod_id(mid);
|
||||
if (o == NULL || o == JNIMethodBlock::_free_method || !((Metadata*)o)->is_method()) {
|
||||
if (o == NULL || o == JNIMethodBlock::_free_method) {
|
||||
return NULL;
|
||||
}
|
||||
return o;
|
||||
// Method should otherwise be valid. Assert for testing.
|
||||
assert(is_valid_method(o), "should be valid jmethodid");
|
||||
// If the method's class holder object is unreferenced, but not yet marked as
|
||||
// unloaded, we need to return NULL here too because after a safepoint, its memory
|
||||
// will be reclaimed.
|
||||
return o->method_holder()->is_loader_alive() ? o : NULL;
|
||||
};
|
||||
|
||||
void Method::set_on_stack(const bool value) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue