JvmPauseMonitor类源码解析(hadoop2.7)

类描述信息:

Class which sets up a simple thread which runs in a loop sleeping for a short interval of time. If the sleep takes significantly longer than its target time, it implies that the JVM or host machine has paused processing, which may cause other problems. If such a pause is detected, the thread logs a message.

1. 入口main函数:

public static void main(String []args) throws Exception {
    new JvmPauseMonitor(new Configuration()).start();
    List<String> list = Lists.newArrayList();
    int i = 0;
    while (true) {
      list.add(String.valueOf(i++));
    }
  }
public void start() {
    Preconditions.checkState(monitorThread == null,
        "Already started");
    monitorThread = new Daemon(new Monitor());
    monitorThread.start();
  }

可见,构造了Monitor实例的守护线程并调用start方法,下面来解析下所有相关的类:JvmPauseMonitor、静态内部类GcTimes、Monitor;

2. JvmPauseMonitor:定义监控用的一些变量和常量: 例如警告时间、告警阀值次数、提示阀值次数等

 private static final Log LOG = LogFactory.getLog(JvmPauseMonitor.class);
 
  /** The target sleep time */
  private static final long SLEEP_INTERVAL_MS = 500;//sleep的时间
  
  /** log WARN if we detect a pause longer than this threshold */
  private final long warnThresholdMs; //成员变量,警告时间,如果超时到此时间,则发出警告。
  private static final String WARN_THRESHOLD_KEY = "jvm.pause.warn-threshold.ms"; // 设置警告时间的配置项
  private static final long WARN_THRESHOLD_DEFAULT = 10000; //静态变量,默认警告时间,如果超时到此时间,则发出警告。
  
  /** log INFO if we detect a pause longer than this threshold */
  private final long infoThresholdMs; //打印提示时间
  private static final String INFO_THRESHOLD_KEY =   "jvm.pause.info-threshold.ms"; //设置提示时间的配置项
  private static final long INFO_THRESHOLD_DEFAULT = 1000; //静态变量,默认提示时间,如果超时到此时间,则发出提示。
 
  private long numGcWarnThresholdExceeded = 0; //超过告警阈值的次数
  private long numGcInfoThresholdExceeded = 0; //超过提示阈值的次数
  private long totalGcExtraSleepTime = 0;//总的GC导致的另外花费时间
   
  private Thread monitorThread;//监控线程,就是在此线程中循环调用sleep,并且计算时间的。
  private volatile boolean shouldRun = true;//是否应该运行。

GcTimes: 维护gc次数和gc 时间的变量

private static class GcTimes {
    private GcTimes(GarbageCollectorMXBean gcBean) {
      gcCount = gcBean.getCollectionCount();
      gcTimeMillis = gcBean.getCollectionTime();
    }
    
    private GcTimes(long count, long time) {
      this.gcCount = count;
      this.gcTimeMillis = time;
    }

    private GcTimes subtract(GcTimes other) {
      return new GcTimes(this.gcCount - other.gcCount,
          this.gcTimeMillis - other.gcTimeMillis);
    }
    
    @Override
    public String toString() {
      return "count=" + gcCount + " time=" + gcTimeMillis + "ms";
    }
    
    private long gcCount;
    private long gcTimeMillis;
  }

3. Monitor: 通过调用sleep方法对比睡眠时间和目标时间的差值,如果超过阀值会打印warn后者info log;

private class Monitor implements Runnable {
    @Override
    public void run() {
      StopWatch sw = new StopWatch();
      Map<String, GcTimes> gcTimesBeforeSleep = getGcTimes();
      while (shouldRun) {
        sw.reset().start();
        try {
          Thread.sleep(SLEEP_INTERVAL_MS);
        } catch (InterruptedException ie) {
          return;
        }
        long extraSleepTime = sw.now(TimeUnit.MILLISECONDS) - SLEEP_INTERVAL_MS;
        Map<String, GcTimes> gcTimesAfterSleep = getGcTimes();

        if (extraSleepTime > warnThresholdMs) {
          ++numGcWarnThresholdExceeded;
          LOG.warn(formatMessage(
              extraSleepTime, gcTimesAfterSleep, gcTimesBeforeSleep));
        } else if (extraSleepTime > infoThresholdMs) {
          ++numGcInfoThresholdExceeded;
          LOG.info(formatMessage(
              extraSleepTime, gcTimesAfterSleep, gcTimesBeforeSleep));
        }
        totalGcExtraSleepTime += extraSleepTime;
        gcTimesBeforeSleep = gcTimesAfterSleep;
      }
    }
  }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值