mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 04:24:49 +02:00
8009298: NMT: Special version of class loading/unloading with runThese stresses out NMT
8009777: NMT: add new NMT dcmd to control auto shutdown option Added diagnostic VM option and DCmd command to allow NMT stay alive under stress situation Reviewed-by: dcubed, coleenp
This commit is contained in:
parent
3277de9dad
commit
b799726f35
5 changed files with 52 additions and 8 deletions
|
@ -869,6 +869,11 @@ class CommandLineFlags {
|
||||||
diagnostic(bool, PrintNMTStatistics, false, \
|
diagnostic(bool, PrintNMTStatistics, false, \
|
||||||
"Print native memory tracking summary data if it is on") \
|
"Print native memory tracking summary data if it is on") \
|
||||||
\
|
\
|
||||||
|
diagnostic(bool, AutoShutdownNMT, true, \
|
||||||
|
"Automatically shutdown native memory tracking under stress " \
|
||||||
|
"situation. When set to false, native memory tracking tries to " \
|
||||||
|
"stay alive at the expense of JVM performance") \
|
||||||
|
\
|
||||||
diagnostic(bool, LogCompilation, false, \
|
diagnostic(bool, LogCompilation, false, \
|
||||||
"Log compilation activity in detail to hotspot.log or LogFile") \
|
"Log compilation activity in detail to hotspot.log or LogFile") \
|
||||||
\
|
\
|
||||||
|
|
|
@ -68,6 +68,7 @@ int MemTracker::_thread_count = 255;
|
||||||
volatile jint MemTracker::_pooled_recorder_count = 0;
|
volatile jint MemTracker::_pooled_recorder_count = 0;
|
||||||
volatile unsigned long MemTracker::_processing_generation = 0;
|
volatile unsigned long MemTracker::_processing_generation = 0;
|
||||||
volatile bool MemTracker::_worker_thread_idle = false;
|
volatile bool MemTracker::_worker_thread_idle = false;
|
||||||
|
volatile bool MemTracker::_slowdown_calling_thread = false;
|
||||||
debug_only(intx MemTracker::_main_thread_tid = 0;)
|
debug_only(intx MemTracker::_main_thread_tid = 0;)
|
||||||
NOT_PRODUCT(volatile jint MemTracker::_pending_recorder_count = 0;)
|
NOT_PRODUCT(volatile jint MemTracker::_pending_recorder_count = 0;)
|
||||||
|
|
||||||
|
@ -364,6 +365,12 @@ void MemTracker::create_memory_record(address addr, MEMFLAGS flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread != NULL) {
|
if (thread != NULL) {
|
||||||
|
// slow down all calling threads except NMT worker thread, so it
|
||||||
|
// can catch up.
|
||||||
|
if (_slowdown_calling_thread && thread != _worker_thread) {
|
||||||
|
os::yield_all();
|
||||||
|
}
|
||||||
|
|
||||||
if (thread->is_Java_thread() && ((JavaThread*)thread)->is_safepoint_visible()) {
|
if (thread->is_Java_thread() && ((JavaThread*)thread)->is_safepoint_visible()) {
|
||||||
JavaThread* java_thread = (JavaThread*)thread;
|
JavaThread* java_thread = (JavaThread*)thread;
|
||||||
JavaThreadState state = java_thread->thread_state();
|
JavaThreadState state = java_thread->thread_state();
|
||||||
|
@ -442,6 +449,7 @@ void MemTracker::enqueue_pending_recorder(MemRecorder* rec) {
|
||||||
#define MAX_SAFEPOINTS_TO_SKIP 128
|
#define MAX_SAFEPOINTS_TO_SKIP 128
|
||||||
#define SAFE_SEQUENCE_THRESHOLD 30
|
#define SAFE_SEQUENCE_THRESHOLD 30
|
||||||
#define HIGH_GENERATION_THRESHOLD 60
|
#define HIGH_GENERATION_THRESHOLD 60
|
||||||
|
#define MAX_RECORDER_THREAD_RATIO 30
|
||||||
|
|
||||||
void MemTracker::sync() {
|
void MemTracker::sync() {
|
||||||
assert(_tracking_level > NMT_off, "NMT is not enabled");
|
assert(_tracking_level > NMT_off, "NMT is not enabled");
|
||||||
|
@ -487,6 +495,13 @@ void MemTracker::sync() {
|
||||||
pending_recorders = _global_recorder;
|
pending_recorders = _global_recorder;
|
||||||
_global_recorder = NULL;
|
_global_recorder = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// see if NMT has too many outstanding recorder instances, it usually
|
||||||
|
// means that worker thread is lagging behind in processing them.
|
||||||
|
if (!AutoShutdownNMT) {
|
||||||
|
_slowdown_calling_thread = (MemRecorder::_instance_count > MAX_RECORDER_THREAD_RATIO * _thread_count);
|
||||||
|
}
|
||||||
|
|
||||||
// check _worker_thread with lock to avoid racing condition
|
// check _worker_thread with lock to avoid racing condition
|
||||||
if (_worker_thread != NULL) {
|
if (_worker_thread != NULL) {
|
||||||
_worker_thread->at_sync_point(pending_recorders, InstanceKlass::number_of_instance_classes());
|
_worker_thread->at_sync_point(pending_recorders, InstanceKlass::number_of_instance_classes());
|
||||||
|
|
|
@ -84,6 +84,7 @@ class MemTracker : AllStatic {
|
||||||
static inline bool baseline() { return false; }
|
static inline bool baseline() { return false; }
|
||||||
static inline bool has_baseline() { return false; }
|
static inline bool has_baseline() { return false; }
|
||||||
|
|
||||||
|
static inline void set_autoShutdown(bool value) { }
|
||||||
static void shutdown(ShutdownReason reason) { }
|
static void shutdown(ShutdownReason reason) { }
|
||||||
static inline bool shutdown_in_progress() { }
|
static inline bool shutdown_in_progress() { }
|
||||||
static bool print_memory_usage(BaselineOutputer& out, size_t unit,
|
static bool print_memory_usage(BaselineOutputer& out, size_t unit,
|
||||||
|
@ -238,6 +239,16 @@ class MemTracker : AllStatic {
|
||||||
// if native memory tracking tracks callsite
|
// if native memory tracking tracks callsite
|
||||||
static inline bool track_callsite() { return _tracking_level == NMT_detail; }
|
static inline bool track_callsite() { return _tracking_level == NMT_detail; }
|
||||||
|
|
||||||
|
// NMT automatically shuts itself down under extreme situation by default.
|
||||||
|
// When the value is set to false, NMT will try its best to stay alive,
|
||||||
|
// even it has to slow down VM.
|
||||||
|
static inline void set_autoShutdown(bool value) {
|
||||||
|
AutoShutdownNMT = value;
|
||||||
|
if (AutoShutdownNMT && _slowdown_calling_thread) {
|
||||||
|
_slowdown_calling_thread = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// shutdown native memory tracking capability. Native memory tracking
|
// shutdown native memory tracking capability. Native memory tracking
|
||||||
// can be shutdown by VM when it encounters low memory scenarios.
|
// can be shutdown by VM when it encounters low memory scenarios.
|
||||||
// Memory tracker should gracefully shutdown itself, and preserve the
|
// Memory tracker should gracefully shutdown itself, and preserve the
|
||||||
|
@ -507,6 +518,10 @@ class MemTracker : AllStatic {
|
||||||
// although NMT is still procesing current generation, but
|
// although NMT is still procesing current generation, but
|
||||||
// there is not more recorder to process, set idle state
|
// there is not more recorder to process, set idle state
|
||||||
static volatile bool _worker_thread_idle;
|
static volatile bool _worker_thread_idle;
|
||||||
|
|
||||||
|
// if NMT should slow down calling thread to allow
|
||||||
|
// worker thread to catch up
|
||||||
|
static volatile bool _slowdown_calling_thread;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !INCLUDE_NMT
|
#endif // !INCLUDE_NMT
|
||||||
|
|
|
@ -49,6 +49,9 @@ NMTDCmd::NMTDCmd(outputStream* output,
|
||||||
_shutdown("shutdown", "request runtime to shutdown itself and free the " \
|
_shutdown("shutdown", "request runtime to shutdown itself and free the " \
|
||||||
"memory used by runtime.",
|
"memory used by runtime.",
|
||||||
"BOOLEAN", false, "false"),
|
"BOOLEAN", false, "false"),
|
||||||
|
_auto_shutdown("autoShutdown", "automatically shutdown itself under " \
|
||||||
|
"stress situation",
|
||||||
|
"BOOLEAN", true, "true"),
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
_debug("debug", "print tracker statistics. Debug only, not thread safe", \
|
_debug("debug", "print tracker statistics. Debug only, not thread safe", \
|
||||||
"BOOLEAN", false, "false"),
|
"BOOLEAN", false, "false"),
|
||||||
|
@ -61,6 +64,7 @@ NMTDCmd::NMTDCmd(outputStream* output,
|
||||||
_dcmdparser.add_dcmd_option(&_summary_diff);
|
_dcmdparser.add_dcmd_option(&_summary_diff);
|
||||||
_dcmdparser.add_dcmd_option(&_detail_diff);
|
_dcmdparser.add_dcmd_option(&_detail_diff);
|
||||||
_dcmdparser.add_dcmd_option(&_shutdown);
|
_dcmdparser.add_dcmd_option(&_shutdown);
|
||||||
|
_dcmdparser.add_dcmd_option(&_auto_shutdown);
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
_dcmdparser.add_dcmd_option(&_debug);
|
_dcmdparser.add_dcmd_option(&_debug);
|
||||||
#endif
|
#endif
|
||||||
|
@ -84,17 +88,19 @@ void NMTDCmd::execute(TRAPS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int nopt = 0;
|
int nopt = 0;
|
||||||
if(_summary.is_set() && _summary.value()) { ++nopt; }
|
if (_summary.is_set() && _summary.value()) { ++nopt; }
|
||||||
if(_detail.is_set() && _detail.value()) { ++nopt; }
|
if (_detail.is_set() && _detail.value()) { ++nopt; }
|
||||||
if(_baseline.is_set() && _baseline.value()) { ++nopt; }
|
if (_baseline.is_set() && _baseline.value()) { ++nopt; }
|
||||||
if(_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
|
if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
|
||||||
if(_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
|
if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
|
||||||
if(_shutdown.is_set() && _shutdown.value()) { ++nopt; }
|
if (_shutdown.is_set() && _shutdown.value()) { ++nopt; }
|
||||||
|
if (_auto_shutdown.is_set()) { ++nopt; }
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
if(_debug.is_set() && _debug.value()) { ++nopt; }
|
if (_debug.is_set() && _debug.value()) { ++nopt; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(nopt > 1) {
|
if (nopt > 1) {
|
||||||
output()->print_cr("At most one of the following option can be specified: " \
|
output()->print_cr("At most one of the following option can be specified: " \
|
||||||
"summary, detail, baseline, summary.diff, detail.diff, shutdown"
|
"summary, detail, baseline, summary.diff, detail.diff, shutdown"
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
|
@ -156,6 +162,8 @@ void NMTDCmd::execute(TRAPS) {
|
||||||
MemTracker::shutdown(MemTracker::NMT_shutdown_user);
|
MemTracker::shutdown(MemTracker::NMT_shutdown_user);
|
||||||
output()->print_cr("Shutdown is in progress, it will take a few moments to " \
|
output()->print_cr("Shutdown is in progress, it will take a few moments to " \
|
||||||
"completely shutdown");
|
"completely shutdown");
|
||||||
|
} else if (_auto_shutdown.is_set()) {
|
||||||
|
MemTracker::set_autoShutdown(_auto_shutdown.value());
|
||||||
} else {
|
} else {
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
output()->print_cr("Unknown command");
|
output()->print_cr("Unknown command");
|
||||||
|
|
|
@ -39,6 +39,7 @@ class NMTDCmd: public DCmdWithParser {
|
||||||
DCmdArgument<bool> _summary_diff;
|
DCmdArgument<bool> _summary_diff;
|
||||||
DCmdArgument<bool> _detail_diff;
|
DCmdArgument<bool> _detail_diff;
|
||||||
DCmdArgument<bool> _shutdown;
|
DCmdArgument<bool> _shutdown;
|
||||||
|
DCmdArgument<bool> _auto_shutdown;
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
DCmdArgument<bool> _debug;
|
DCmdArgument<bool> _debug;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue