8056240: Investigate increased GC remark time after class unloading changes in CRM Fuse

Reviewed-by: mgerdin, coleenp, bdelsart
This commit is contained in:
Stefan Karlsson 2014-10-02 10:55:36 +02:00
parent 1055ae0436
commit d410f19961
19 changed files with 506 additions and 68 deletions

View file

@ -734,7 +734,7 @@ bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) {
// 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;
@ -743,27 +743,9 @@ bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) {
// 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(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.
while (data != NULL) {
if (data->is_alive(is_alive_closure)) {
data->classes_do(InstanceKlass::purge_previous_versions);
}
data = data->next();
}
}
data = _head;
while (data != NULL) {
if (data->is_alive(is_alive_closure)) {
data->free_deallocate_list();
prev = data;
data = data->next();
continue;
@ -785,6 +767,11 @@ bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) {
_unloading = dead;
}
if (clean_alive) {
// Clean previous versions and the deallocate list.
ClassLoaderDataGraph::clean_metaspaces();
}
if (seen_dead_loader) {
post_class_unload_events();
}
@ -792,6 +779,26 @@ bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) {
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;
@ -819,6 +826,14 @@ void ClassLoaderDataGraph::post_class_unload_events(void) {
#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