< prev index next >
src/share/vm/classfile/classLoaderData.cpp
Print this page
rev 6875 : 8056240: Investigate increased GC remark time after class unloading changes in CRM Fuse
Reviewed-by: mgerdin, coleenp, bdelsart
@@ -745,29 +745,21 @@
#endif // PRODUCT
// Move class loader data from main list to the unloaded list for unloading
// and deallocation later.
-bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) {
+bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure, bool clean_alive) {
ClassLoaderData* data = _head;
ClassLoaderData* prev = NULL;
bool seen_dead_loader = false;
// Save previous _unloading pointer for CMS which may add to unloading list before
// purging and we don't want to rewalk the previously unloaded class loader data.
_saved_unloading = _unloading;
- // mark metadata seen on the stack and code cache so we can delete
- // unneeded entries.
- bool has_redefined_a_class = JvmtiExport::has_redefined_a_class();
- MetadataOnStackMark md_on_stack;
while (data != NULL) {
if (data->is_alive(is_alive_closure)) {
- if (has_redefined_a_class) {
- data->classes_do(InstanceKlass::purge_previous_versions);
- }
- data->free_deallocate_list();
prev = data;
data = data->next();
continue;
}
seen_dead_loader = true;
@@ -785,17 +777,42 @@
}
dead->set_next(_unloading);
_unloading = dead;
}
+ if (clean_alive) {
+ // Clean previous versions and the deallocate list.
+ ClassLoaderDataGraph::clean_metaspaces();
+ }
+
if (seen_dead_loader) {
post_class_unload_events();
}
return seen_dead_loader;
}
+void ClassLoaderDataGraph::clean_metaspaces() {
+ // mark metadata seen on the stack and code cache so we can delete unneeded entries.
+ bool has_redefined_a_class = JvmtiExport::has_redefined_a_class();
+ MetadataOnStackMark md_on_stack(has_redefined_a_class);
+
+ if (has_redefined_a_class) {
+ // purge_previous_versions also cleans weak method links. Because
+ // one method's MDO can reference another method from another
+ // class loader, we need to first clean weak method links for all
+ // class loaders here. Below, we can then free redefined methods
+ // for all class loaders.
+ for (ClassLoaderData* data = _head; data != NULL; data = data->next()) {
+ data->classes_do(InstanceKlass::purge_previous_versions);
+ }
+ }
+
+ // Need to purge the previous version before deallocating.
+ free_deallocate_lists();
+}
+
void ClassLoaderDataGraph::purge() {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
ClassLoaderData* list = _unloading;
_unloading = NULL;
ClassLoaderData* next = list;
@@ -819,10 +836,18 @@
Tracing::on_unloading_classes();
}
#endif
}
+void ClassLoaderDataGraph::free_deallocate_lists() {
+ for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+ // We need to keep this data until InstanceKlass::purge_previous_version has been
+ // called on all alive classes. See the comment in ClassLoaderDataGraph::clean_metaspaces.
+ cld->free_deallocate_list();
+ }
+}
+
// CDS support
// Global metaspaces for writing information to the shared archive. When
// application CDS is supported, we may need one per metaspace, so this
// sort of looks like it.
< prev index next >