Java程序如何发现自己经历了长时间的GC暂停?

时间:2018-09-30 03:37:20

标签: java garbage-collection monitor

我正在编写一个可能具有较长GC暂停的程序,但是SLA表示我不应有太多暂停。并且需要报告是否找到它。

如何使其能够自我监控?我不想解析GC日志。

JMX公开了LastGcInfo,但我不知道何时查询它。

3 个答案:

答案 0 :(得分:0)

让应用程序处理GC在用户代码空间中进行相关监视不是一个好主意。有时应用程序处于状态(接近OOM),它将无法执行用户代码,并且监视可能会中断。

如果您仍要这样做(请自担风险),可以像这样将侦听器挂接到GC并检查GC的持续时间。

for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) {
    NotificationEmitter emitter = (NotificationEmitter) gcBean;
    emitter.addNotificationListener(new CustomNotificationListener(), null, null);
}

class CustomNotificationListener implements javax.management.NotificationListener {
        @Override
        public void handleNotification(Notification notification, Object handback) {
            // hook your logic here.
          String notifType = notification.getType();
          if (notifType.equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
              // retrieve the garbage collection notification information
              CompositeData cd = (CompositeData) notification.getUserData();
              GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from(cd);
              System.out.println(info.getGcInfo().getDuration());
          }
        }
}

答案 1 :(得分:0)

@Jigar的答案显示了如何监视GC事件。但是,我认为这不会允许一个线程测量它...或另一个线程...被暂停了多长时间。

事实上,我怀疑没有一种方法可以衡量。

实际上,我也不认为有办法测量其他类型的停顿。例如

  • 由于等待I / O而暂停
  • 由于同步而暂停,或者
  • 由于操作系统控制的时间片而暂停。

我认为您想做的事不可行,更不用说建议了。


查看您的要求:

  

我正在编写一个可能具有较长GC暂停的程序,但是SLA表示我不应有太多暂停。并且需要报告是否找到它。

  1. 根据GC暂停 1 可能未满足SLA。将根据响应时间进行介绍。那有很大的不同。响应时间比GC暂停要容易得多。

  2. SLA不太可能说您必​​须测量应用程序本身中的响应时间(或其他任何时间)。因此,请在外部进行测量:

    • 在单独的实时监视系统中分析应用程序/ Web容器日志事件;例如Nagios,CheckMk等。
    • 事后扫描应用程序/ Web容器日志文件。
    • 将数据包或流监视连接到记录响应时间的内容。

如果您决定忽略2),请考虑您放入Java应用程序中以进行“自我监视”的任何其他基础结构将使其变得更加复杂,并且(除非您小心)增加了GC负载,从而使GC暂停更频繁

简而言之:由于您可能不需要这样做,因此,我考虑的建议是不要尝试检测应用程序本身中的GC暂停。


1-如果是,那么有人在编写/协商SLA时出错了!

答案 2 :(得分:0)

在直接转到付费Java APM应用程序或临时实现之前,请看一下Glowroot

它是免费的开放源代码,使您可以监视一系列指标,包括GC收集时间,堆使用情况。也可以将带有警报的电子邮件发送给您和您的合作者。

几乎没有overhead。我已经有一段时间将它用于预算很少甚至根本没有预算的应用程序了。

尝试一下(这里是demo),然后选择一个更适合您需求的APM。