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

How can a java program find itself has experienced a long GC pause?

我正在编写一个可以有长时间 GC 暂停的程序,但是 SLA 说我不应该有太多暂停。如果它发现任何东西,它需要报告。

如何让它监控自己?我不想解析 GC 日志。

JMX暴露了LastGcInfo,但是不知道什么时候查询

在用户代码中让应用程序处理 GC 相关监控并不是一个好主意space。有时应用程序处于状态(接近 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());
          }
        }
}

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

事实上,我怀疑没有办法衡量它。

事实上,我认为也没有办法衡量其他类型的停顿;例如

  • 因等待 I/O
  • 而暂停
  • 由于同步而暂停,或
  • 由于 OS 受控时间片而暂停。

我认为你想做的事情不可行,更不明智。


查看您的要求:

I am writing a program that can have long GC pauses, however the SLA said I shouldn't have too many of them. And it needs to report if it finds any.

  1. SLA 可能没有在 GC 暂停方面提出 1。它将根据响应时间来表达。这有很大的不同。响应时间比 GC 暂停更容易衡量。

  2. SLA 不太可能说您必​​须测量应用程序本身的响应时间(或其他)。所以在外面量一下:

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

如果您决定忽略 2),请考虑您在 Java 到 "self monitor" 应用程序中放入的任何额外基础设施都会使其变得更加复杂,并且(除非您小心)添加GC 负载,使 GC 暂停 更频繁

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


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

在直接跳转到付费 Java APM 应用程序或临时实施之前,请先查看 Glowroot

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

很少有人会注意到 overhead。我已经将它用于预算很少或根本没有预算的应用程序一段时间了。

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