Reputation: 1100
"VM Periodic Task Thread"
Aka the "WatcherThread". This is a VM thread that performs periodic tasks, e.g., updating performance counters.
see link
Periodic task scheduling of threads, it was founded by WatcherThread, is a singleton object.
The thread in JVM more frequently used, For example, the running status of the memory monitoring, JVM monitoring regularly. And we often need to perform some
jstat
this command for the GC case.As follows:
jstat -gcutil 234832507
making this command tells the JVM in the console to print PID: GC 23483, An interval of 250 msec print a, A total of over 7 prints.
see link
This is what I find in the JVM source code.
I think when the "VM Periodic Task Thread"(WatcherThread) starts, it should perform "run" function.
The only thing I notice is that it spins in the while loop,
but how does WatcherThread invoke JVM monitoring routines, like jstat
?
Where is the sub-routine of jstat
in this while loop?
I am curious how WatcherThread updates performance counters and things like that.
void WatcherThread::run() {
assert(this == watcher_thread(), "just checking");
this->record_stack_base_and_size();
this->set_native_thread_name(this->name());
this->set_active_handles(JNIHandleBlock::allocate_block());
while (true) {
assert(watcher_thread() == Thread::current(), "thread consistency check");
assert(watcher_thread() == this, "thread consistency check");
// Calculate how long it'll be until the next PeriodicTask work
// should be done, and sleep that amount of time.
int time_waited = sleep(); // return 50
if (is_error_reported()) {
// A fatal error has happened, the error handler(VMError::report_and_die)
// should abort JVM after creating an error log file. However in some
// rare cases, the error handler itself might deadlock. Here we try to
// kill JVM if the fatal error handler fails to abort in 2 minutes.
//
// This code is in WatcherThread because WatcherThread wakes up
// periodically so the fatal error handler doesn't need to do anything;
// also because the WatcherThread is less likely to crash than other
// threads.
for (;;) {
if (!ShowMessageBoxOnError
&& (OnError == NULL || OnError[0] == '\0')
&& Arguments::abort_hook() == NULL) {
os::sleep(this, (jlong)ErrorLogTimeout * 1000, false); // in seconds
fdStream err(defaultStream::output_fd());
err.print_raw_cr("# [ timer expired, abort... ]");
// skip atexit/vm_exit/vm_abort hooks
os::die();
}
// Wake up 5 seconds later, the fatal handler may reset OnError or
// ShowMessageBoxOnError when it is ready to abort.
os::sleep(this, 5 * 1000, false);
}
}
if (_should_terminate) {
// check for termination before posting the next tick
break;
}
PeriodicTask::real_time_tick(time_waited);
}
// Signal that it is terminated
{
MutexLockerEx mu(Terminator_lock, Mutex::_no_safepoint_check_flag);
_watcher_thread = NULL;
Terminator_lock->notify();
}
}
Upvotes: 0
Views: 474
Reputation: 98580
Obviously JVM does not call jstat
or other external utilities.
You are probably looking for StatSampler::collect_sample
:
/*
* the collect_sample() method is the method invoked by the
* WatcherThread via the PeriodicTask::task() method. This method
* is responsible for collecting data samples from sampled
* PerfData instances every PerfDataSamplingInterval milliseconds.
* It is also responsible for logging the requested set of
* PerfData instances every _sample_count milliseconds. While
* logging data, it will output a column header after every _print_header
* rows of data have been logged.
*/
void StatSampler::collect_sample() {
WatcherThread
executes registered instances of PeriodicTask
class, and StatSamplerTask
is one of such tasks.
Upvotes: 1