@Override
  public void getMetrics(MetricsCollector collector, boolean all) {
    MetricsRecordBuilder rb = collector.addRecord(JvmMetrics)
        .setContext("jvm").tag(ProcessName, processName)
        .tag(SessionId, sessionId);
    getMemoryUsage(rb);
    getGcUsage(rb);
    if (threadMXBean != null) {
      getThreadUsage(rb);
    } else {
      getThreadUsageFromGroup(rb);
    }
  }
@Test
  public void testGetMetricsPerf() {
    JvmMetrics jvmMetricsUseMXBean = new JvmMetrics("test", "test", true);
    JvmMetrics jvmMetrics = new JvmMetrics("test", "test", false);
    MetricsCollectorImpl collector = new MetricsCollectorImpl();
    // warm up
    jvmMetrics.getMetrics(collector, true);
    jvmMetricsUseMXBean.getMetrics(collector, true);
    // test cases with different numbers of threads
    int[] numThreadsCases = {100, 200, 500, 1000, 2000, 3000};
    List<TestThread> threads = new ArrayList();
    for (int numThreads : numThreadsCases) {
      updateThreadsAndWait(threads, numThreads);
      long startNs = System.nanoTime();
      jvmMetricsUseMXBean.getMetrics(collector, true);
      long processingNsFromMXBean = System.nanoTime() - startNs;
      startNs = System.nanoTime();
      jvmMetrics.getMetrics(collector, true);
      long processingNsFromGroup = System.nanoTime() - startNs;
      System.out.println(
          "#Threads=" + numThreads + ", ThreadMXBean=" + processingNsFromMXBean
              + " ns, ThreadGroup=" + processingNsFromGroup + " ns, ratio: " + (
              processingNsFromMXBean / processingNsFromGroup));
    }
    // cleanup
    updateThreadsAndWait(threads, 0);
  }