8264644: Add PrintClassLoaderDataGraphAtExit to print the detailed CLD graph

Reviewed-by: coleenp, dholmes, shade
This commit is contained in:
Yi Yang 2021-04-12 08:23:20 +00:00 committed by Aleksey Shipilev
parent b1ebf82269
commit 440c34a62b
6 changed files with 61 additions and 15 deletions

View File

@ -930,20 +930,57 @@ void ClassLoaderData::print_value_on(outputStream* out) const {
void ClassLoaderData::print_value() const { print_value_on(tty); }
#ifndef PRODUCT
void ClassLoaderData::print_on(outputStream* out) const {
out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: %s {",
p2i(this), p2i(_class_loader.ptr_raw()), loader_name_and_id());
if (has_class_mirror_holder()) out->print(" has a class holder");
if (claimed()) out->print(" claimed");
if (is_unloading()) out->print(" unloading");
out->print(" metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null()));
class PrintKlassClosure: public KlassClosure {
outputStream* _out;
public:
PrintKlassClosure(outputStream* out): _out(out) { }
if (_jmethod_ids != NULL) {
Method::print_jmethod_ids(this, out);
void do_klass(Klass* k) {
ResourceMark rm;
_out->print("%s,", k->external_name());
}
out->print(" handles count %d", _handles.count());
out->print(" dependencies %d", _dependency_count);
out->print_cr("}");
};
void ClassLoaderData::print_on(outputStream* out) const {
ResourceMark rm;
out->print_cr("ClassLoaderData(" INTPTR_FORMAT ")", p2i(this));
out->print_cr(" - name %s", loader_name_and_id());
if (!_holder.is_null()) {
out->print (" - holder ");
_holder.print_on(out);
out->print_cr("");
}
out->print_cr(" - class loader " INTPTR_FORMAT, p2i(_class_loader.ptr_raw()));
out->print_cr(" - metaspace " INTPTR_FORMAT, p2i(_metaspace));
out->print_cr(" - unloading %s", _unloading ? "true" : "false");
out->print_cr(" - class mirror holder %s", _has_class_mirror_holder ? "true" : "false");
out->print_cr(" - modified oops %s", _modified_oops ? "true" : "false");
out->print_cr(" - keep alive %d", _keep_alive);
out->print (" - claim ");
switch(_claim) {
case _claim_none: out->print_cr("none"); break;
case _claim_finalizable:out->print_cr("finalizable"); break;
case _claim_strong: out->print_cr("strong"); break;
case _claim_other: out->print_cr("other"); break;
default: ShouldNotReachHere();
}
out->print_cr(" - handles %d", _handles.count());
out->print_cr(" - dependency count %d", _dependency_count);
out->print (" - klasses {");
PrintKlassClosure closure(out);
((ClassLoaderData*)this)->classes_do(&closure);
out->print_cr(" }");
out->print_cr(" - packages " INTPTR_FORMAT, p2i(_packages));
out->print_cr(" - module " INTPTR_FORMAT, p2i(_modules));
out->print_cr(" - unnamed module " INTPTR_FORMAT, p2i(_unnamed_module));
out->print_cr(" - dictionary " INTPTR_FORMAT, p2i(_dictionary));
if (_jmethod_ids != NULL) {
out->print (" - jmethod count ");
Method::print_jmethod_ids_count(this, out);
out->print_cr("");
}
out->print_cr(" - deallocate list " INTPTR_FORMAT, p2i(_deallocate_list));
out->print_cr(" - next CLD " INTPTR_FORMAT, p2i(_next));
}
#endif // PRODUCT

View File

@ -673,6 +673,7 @@ void ClassLoaderDataGraph::verify() {
// callable from debugger
extern "C" int print_loader_data_graph() {
ResourceMark rm;
MutexLocker ml(ClassLoaderDataGraph_lock);
ClassLoaderDataGraph::print_on(tty);
return 0;
}

View File

@ -2255,8 +2255,8 @@ bool Method::is_valid_method(const Method* m) {
}
#ifndef PRODUCT
void Method::print_jmethod_ids(const ClassLoaderData* loader_data, outputStream* out) {
out->print(" jni_method_id count = %d", loader_data->jmethod_ids()->count_methods());
void Method::print_jmethod_ids_count(const ClassLoaderData* loader_data, outputStream* out) {
out->print("%d", loader_data->jmethod_ids()->count_methods());
}
#endif // PRODUCT

View File

@ -822,7 +822,7 @@ public:
// Clear methods
static void clear_jmethod_ids(ClassLoaderData* loader_data);
static void print_jmethod_ids(const ClassLoaderData* loader_data, outputStream* out) PRODUCT_RETURN;
static void print_jmethod_ids_count(const ClassLoaderData* loader_data, outputStream* out) PRODUCT_RETURN;
// Get this method's jmethodID -- allocate if it doesn't exist
jmethodID jmethod_id();

View File

@ -686,6 +686,9 @@ const intx ObjectAlignmentInBytes = 8;
notproduct(bool, PrintSystemDictionaryAtExit, false, \
"Print the system dictionary at exit") \
\
notproduct(bool, PrintClassLoaderDataGraphAtExit, false, \
"Print the class loader data graph at exit") \
\
product(bool, DynamicallyResizeSystemDictionaries, true, DIAGNOSTIC, \
"Dynamically resize system dictionaries as needed") \
\

View File

@ -325,6 +325,11 @@ void print_statistics() {
ResourceMark rm;
MutexLocker mcld(ClassLoaderDataGraph_lock);
SystemDictionary::print();
}
if (PrintClassLoaderDataGraphAtExit) {
ResourceMark rm;
MutexLocker mcld(ClassLoaderDataGraph_lock);
ClassLoaderDataGraph::print();
}