amazonweb服务-如何确定jvm应用程序比正常工作做更多的GC



我们最近遇到了一个问题,我们的EC2实例有90-100%的cpu负载,这是因为我们在一个库中包含了一个错误,该错误是为许多对象创建的,而不是重用它们(这很容易解决),所以我们在GC上花了太多时间。

不幸的是,AWS的健康检查和实例状态指标并没有导致过载的实例停止,然后重新启动新实例,所以一段时间后,我们达到了最大自动缩放数。。。。死亡。此外,我们自己在用于ELB的应用程序中进行的健康检查非常简单,它们的回答频率很高,显然不会导致实例终止。。。并重新启动,这将在相当长的一段时间内缓解这个问题。

我现在的想法是,如果我们在GC中花费了太多时间,那么使用我们的自定义健康检查(它已经包含在ELB健康检查中)来报告失败。

我该如何在应用程序中做这样的事情?

有许多JVM参数允许GC监视

-Xloggc:<file> // logs gc activity to a file
-XX:+PrintGCDetails // tells you how different generations are impacted

您可以自己解析这些日志,也可以使用特定的工具(如GCViewer)来分析gc活动。

使用GarbageCollectorMXBean:

    long gcTime = 0;
    for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) {
        gcTime += gcBean.getCollectionTime();
    }
    long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
    System.out.println("GC ratio: " + (100 * gcTime / jvmUptime) + "%");

您可以使用VisualVM监视JVM内部发生的事情,也可以通过JMX监视远程实例。您没有描述您正在使用的应用程序容器(Apache Tomcat、GlassFish等),您可以在Tomcat的情况下设置这样的JMX连接器。

不要忘记调整AWS中的安全组以获得访问JMX端口的适当权限。

JVM标志PrintGCApplicationConcurrentTimePrintGCApplicationStoppedTime将记录应用程序活动或挂起的时间。它们有点用词不当,因为它们实际上衡量的是进出安全点的时间,而不仅仅是GC。

最新更新