【问题标题】:How can a java program find itself has experienced a long GC pause?java 程序如何发现自己经历了长时间的 GC 暂停?
【发布时间】:2018-09-30 03:37:19
【问题描述】:

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

我怎样才能让它监控自己?我不想解析 GC 日志。

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

【问题讨论】:

  • 您是否考虑过使用任何类似 APM 的应用程序?强制应用程序监控自身并报告错误/事件可能不是扩展基础架构的好选择。
  • “太多”有多少?

标签: java garbage-collection monitor


【解决方案1】:

让应用程序处理用户代码空间中的 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());
          }
        }
}

【讨论】:

    【解决方案2】:

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

    事实上,我怀疑没有办法衡量这一点。

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

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

    我不认为你想做的事情是可行的,更不用说可取了。


    查看您的要求:

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

    1. SLA 可能没有以 GC 暂停的形式表达1。它将根据响应时间来表述。这有很大的不同。响应时间比 GC 暂停更容易衡量。

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

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

    如果您决定忽略 2),请考虑您放入 Java 应用程序以“自我监控”的任何额外基础设施都会使其更加复杂,并且(除非您小心)增加 GC 负载,使 GC暂停更频繁

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


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

    【讨论】:

    • 好吧,我相信 SLA 没有提到 GC。但是我的领导说我负责 GC 暂停。
    • 好。因此,这意味着您没有义务以一种行不通的方式进行监控。我的建议是使用一种替代方法来测量/监控响应时间。
    【解决方案3】:

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

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

    会注意到小overhead。我已经将它用于预算很少或根本没有预算的应用程序。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-30
      • 1970-01-01
      相关资源
      最近更新 更多