3 回答
TA贡献1859条经验 获得超6个赞
我认为这不会允许线程测量它...或另一个线程...暂停的时间。
事实上,我怀疑没有办法衡量这一点。
事实上,我认为也没有一种方法可以衡量其他类型的停顿。例如
由于等待 I/O 而暂停
由于同步而暂停,或
由于操作系统控制的时间切片而暂停。
我不认为你想做的事情是可行的,更不用说可取了。
看你的要求:
我正在编写一个可能有很长 GC 暂停的程序,但是 SLA 说我不应该有太多的暂停。如果发现有,它需要报告。
SLA 可能不是根据 GC 暂停1制定的。它将根据响应时间进行调整。这有很大的不同。响应时间比 GC 暂停更容易测量。
SLA 不太可能说您必须测量应用程序本身的响应时间(或其他时间)。所以在外面测量它:
在单独的实时监控系统中分析应用程序/Web 容器日志事件;例如 Nagios、CheckMk 等。
事后扫描应用程序/Web 容器日志文件。
将数据包或流监控连接到记录响应时间的东西。
如果您决定忽略 2),请考虑您在 Java 应用程序中为“自我监控”而添加的任何额外基础设施都会使其更加复杂,并且(除非您小心)增加了 GC 负载,从而使 GC 暂停更加频繁.
简而言之:由于您可能不需要这样做,我考虑的建议是不要尝试检测应用程序本身中的 GC 暂停。
1 - 如果是,那么有人在编写/协商 SLA 时犯了错误!
TA贡献1829条经验 获得超9个赞
让应用程序处理用户代码空间中的 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());
}
}
}
TA贡献1795条经验 获得超7个赞
在直接跳到付费 Java APM 应用程序或临时实现之前,先看看Glowroot。
它是免费和开源的,让您可以监控一系列指标,包括 GC 收集时间、堆使用情况。还可以向您和您的合作者发送带有警报的电子邮件。
很少会注意到开销。我已经将它用于预算很少或根本没有的应用程序。
试一试(这里是一个演示),然后选择更适合您需求的 APM。
添加回答
举报