WatcherThread 是如何调用 JVM 监控例程的?

How does WatcherThread invoke JVM monitoring routines?

“VM 周期性任务线程”

Aka the "WatcherThread". This is a VM thread that performs periodic tasks, e.g., updating performance counters.

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.

link

这是我在 JVM 源代码中找到的内容。

我认为当“VM Periodic Task Thread”(WatcherThread)启动时,它应该执行“运行”功能。 我唯一注意到的是它在 while 循环中旋转, 但是 WatcherThread 如何调用 JVM 监视例程,如 jstat? 这个while循环中jstat的子程序在哪里? 我很好奇 WatcherThread 是如何更新性能计数器之类的。

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] == '[=10=]')
            && 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();
  }
}

显然 JVM 不会调用 jstat 或其他外部实用程序。

您可能正在寻找 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 执行 PeriodicTask class 的注册实例,StatSamplerTask 是其中一项任务。