8212988: add recent class unloading events to the hs_err log
Summary: also moved class unloading logging in expected place.
Reviewed-by: never, stuefe
--- a/src/hotspot/share/oops/instanceKlass.cpp Wed Feb 13 00:30:46 2019 -0800
+++ b/src/hotspot/share/oops/instanceKlass.cpp Wed Feb 13 06:48:34 2019 -0500
@@ -75,6 +75,7 @@
#include "services/classLoadingService.hpp"
#include "services/threadService.hpp"
#include "utilities/dtrace.hpp"
+#include "utilities/events.hpp"
#include "utilities/macros.hpp"
#include "utilities/stringUtils.hpp"
#ifdef COMPILER1
@@ -2447,6 +2448,13 @@
// notify ClassLoadingService of class unload
ClassLoadingService::notify_class_unloaded(ik);
+ if (log_is_enabled(Info, class, unload)) {
+ ResourceMark rm;
+ log_info(class, unload)("unloading class %s " INTPTR_FORMAT, ik->external_name(), p2i(ik));
+ }
+
+ Events::log_class_unloading(Thread::current(), ik);
+
#if INCLUDE_JFR
assert(ik != NULL, "invariant");
EventClassUnload event;
--- a/src/hotspot/share/services/classLoadingService.cpp Wed Feb 13 00:30:46 2019 -0800
+++ b/src/hotspot/share/services/classLoadingService.cpp Wed Feb 13 06:48:34 2019 -0500
@@ -137,11 +137,6 @@
_class_methods_size->inc(-methods->at(i)->size());
}
}
-
- if (log_is_enabled(Info, class, unload)) {
- ResourceMark rm;
- log_info(class, unload)("unloading class %s " INTPTR_FORMAT , k->external_name(), p2i(k));
- }
}
void ClassLoadingService::notify_class_loaded(InstanceKlass* k, bool shared_class) {
--- a/src/hotspot/share/utilities/events.cpp Wed Feb 13 00:30:46 2019 -0800
+++ b/src/hotspot/share/utilities/events.cpp Wed Feb 13 06:48:34 2019 -0500
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "memory/allocation.inline.hpp"
+#include "oops/instanceKlass.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.inline.hpp"
#include "runtime/osThread.hpp"
@@ -37,6 +38,7 @@
StringEventLog* Events::_messages = NULL;
StringEventLog* Events::_exceptions = NULL;
StringEventLog* Events::_redefinitions = NULL;
+UnloadingEventLog* Events::_class_unloading = NULL;
StringEventLog* Events::_deopt_messages = NULL;
EventLog::EventLog() {
@@ -67,6 +69,7 @@
_messages = new StringEventLog("Events");
_exceptions = new StringEventLog("Internal exceptions");
_redefinitions = new StringEventLog("Classes redefined");
+ _class_unloading = new UnloadingEventLog("Classes unloaded");
_deopt_messages = new StringEventLog("Deoptimization events");
}
}
@@ -96,3 +99,16 @@
Events::log(NULL, "%s", _buffer.buffer());
}
}
+
+void UnloadingEventLog::log(Thread* thread, InstanceKlass* ik) {
+ if (!should_log()) return;
+
+ double timestamp = fetch_timestamp();
+ // Unloading events are single threaded.
+ int index = compute_log_index();
+ _records[index].thread = thread;
+ _records[index].timestamp = timestamp;
+ stringStream st = _records[index].data.stream();
+ st.print("Unloading class " INTPTR_FORMAT " ", p2i(ik));
+ ik->name()->print_value_on(&st);
+}
--- a/src/hotspot/share/utilities/events.hpp Wed Feb 13 00:30:46 2019 -0800
+++ b/src/hotspot/share/utilities/events.hpp Wed Feb 13 06:48:34 2019 -0500
@@ -165,9 +165,17 @@
logv(thread, format, ap);
va_end(ap);
}
-
};
+class InstanceKlass;
+
+// Event log for class unloading events to materialize the class name in place in the log stream.
+class UnloadingEventLog : public EventLogBase<StringLogMessage> {
+ public:
+ UnloadingEventLog(const char* name, int count = LogEventsBufferEntries) : EventLogBase<StringLogMessage>(name, count) {}
+
+ void log(Thread* thread, InstanceKlass* ik);
+};
class Events : AllStatic {
@@ -189,6 +197,8 @@
// Redefinition related messages
static StringEventLog* _redefinitions;
+ // Class unloading events
+ static UnloadingEventLog* _class_unloading;
public:
static void print_all(outputStream* out);
@@ -203,6 +213,8 @@
static void log_redefinition(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
+ static void log_class_unloading(Thread* thread, InstanceKlass* ik);
+
static void log_deopt_message(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
// Register default loggers
@@ -236,6 +248,12 @@
}
}
+inline void Events::log_class_unloading(Thread* thread, InstanceKlass* ik) {
+ if (LogEvents) {
+ _class_unloading->log(thread, ik);
+ }
+}
+
inline void Events::log_deopt_message(Thread* thread, const char* format, ...) {
if (LogEvents) {
va_list ap;