RFR (S): 8011803: release_C_heap_structures is never called for anonymous classes.
Stefan Karlsson
stefan.karlsson at oracle.com
Fri Apr 12 01:48:12 PDT 2013
On 04/11/2013 10:52 PM, Coleen Phillimore wrote:
> Summary: Call this function from CLD::unload() now for anonymous
> classes.
>
> Anonymous classes aren't in the system dictionary so
> release_C_heap_structures isn't called for them if they are unloaded.
> I fixed this for jdk8 because they are in the class loader data graph
> but for jdk7, I don't know how to fix this. They are unloaded by being
> garbage collected after the references are dropped.
>
> Tested with ute tests vm.mvlm.testlist nsk.monitoring.testlist and
> jdk/test/java/lang/invoke tests.
>
> open webrev at http://cr.openjdk.java.net/~coleenp/8011803/
> bug link at http://bugs.sun.com/view_bug.do?bug_id=8011803
I've two comments.
1) It's unfortunate that we now call unload_class() at two different
places in the code. It makes it harder to understand the deallocation of
metadata. It would be better to keep the calls to unload_class() for
ordinary InstanceKlasses and anonymous classes together.
2) This change actually breaks the Tracing class unloading event that
Markus is working on. That code walk the
ClassLoaderDataGraph::_unloading list in
ClassLoaderDataGraph::do_unloading and use the information in the
classes of the CLDs that are about to be unloaded. With this patch they
probably crash because some pointers in the anonymous classes will be
trashed.
I have a suggestion on how to solve both points above. It's probably
easier to show with a pseudo patch:
$ hg diff
diff --git a/src/share/vm/classfile/classLoaderData.cpp
b/src/share/vm/classfile/classLoaderData.cpp
--- a/src/share/vm/classfile/classLoaderData.cpp
+++ b/src/share/vm/classfile/classLoaderData.cpp
@@ -671,7 +671,6 @@
}
seen_dead_loader = true;
ClassLoaderData* dead = data;
- dead->unload();
data = data->next();
// Remove from loader list.
if (prev != NULL) {
@@ -683,9 +682,24 @@
dead->set_next(_unloading);
_unloading = dead;
}
+
+ report_class_unloading_info(_unloading);
+
+ ClassLoaderDataGraph::unload_classes();
+
return seen_dead_loader;
}
+void ClassLoaderDataGraph::unload_classes() {
+ ClassLoaderData* list = _unloading;
+ ClassLoaderData* next = list;
+ while (next != NULL) {
+ for (Klass* k = next->_klasses; k != NULL; k = k->next_link()) {
+ k->unload_class();
+ }
+ }
+}
+
void ClassLoaderDataGraph::purge() {
ClassLoaderData* list = _unloading;
_unloading = NULL;
diff --git a/src/share/vm/classfile/dictionary.cpp
b/src/share/vm/classfile/dictionary.cpp
--- a/src/share/vm/classfile/dictionary.cpp
+++ b/src/share/vm/classfile/dictionary.cpp
@@ -157,9 +157,6 @@
// to be unloaded.
// Notify the debugger and clean up the class.
class_was_unloaded = true;
-
- // perform unloading actions on this class
- ik->unload_class();
}
// Also remove this system dictionary entry.
purge_entry = true;
As a bonus, the dictionary()->do_unloading() will then only do a simple
purge of the SystemDictionary.
What do you think?
thanks,
StefanK
>
> Thanks,
> Coleen
More information about the hotspot-dev
mailing list