Java堆耗尽时失败模式的实际步骤是什么?

时间:2017-07-11 00:01:49

标签: java service jmx

我知道它比“你达到100%的使用率和服务下降”更复杂。我知道,当您接近100%的使用率时,垃圾收集会开始更积极地运行,例如,当您接近时,您会看到GC和CPU使用率的上升。

但随着时间的推移会发生什么?它会不会越来越多,直到我用完CPU?开始掉线?或者最终达到100%并完全崩溃?

有没有一个好方法可以找出我实际上离悬崖边缘有多近?

1 个答案:

答案 0 :(得分:0)

这实际上取决于您的应用程序以及您正在运行的VM(例如,Oracle JVM,IBM JVM,OpenJDK JVM,lme4等)。在Oracle VM上,您可能会在VM退出之前看到以下一项或多项:

  • 频繁的GC循环将VM的CPU使用率推得很高
  • 长时间运行GC循环,VM仅使用1个CPU,100%,而所有其他JVM线程都被阻止。使用CMS收集器时可能会发生这种情况,并且需要运行“停止世界”#34; GC压缩老一代。
  • GC完成后无法分配内存的一个或多个线程将抛出OutOfMemoryError。接下来会发生什么取决于应用程序,即。如果这些是在您的应用程序中执行任何有用的线程的唯一线程,并且这些线程没有捕获异常或者在它们死亡后没有重新启动,那么您的JVM可能会继续运行,但您的应用程序将停止响应或停止进展。
  • 如果GC消耗大量CPU时间并且在每次收集后仅恢复少量内存,则JVM可能会抛出OutOfMemoryError,并显示消息"超出GC开销限制"请参阅Azul Systems JVM
  • 如果您的应用程序使用软/弱引用缓存数据,那么您可能会看到系统资源的负载增加,因为您的应用程序无法使用缓存数据并且必须通过计算它们或从磁盘或某些方式加载它们来重新生成它们其他外部服务。
  • 如果您的应用程序打开了套接字,则GC暂停可能会导致操作系统缓冲区填满,迫使操作系统丢弃数据包。连接另一端的网络客户端/服务器可能会断开连接,因为您的应用程序已成为一个缓慢的消费者,或者因为它错过了太多心跳或超时您的应用程序。

您可以通过启用详细的GC日志记录(请参阅Error java.lang.OutOfMemoryError: GC overhead limit exceeded)和/或通过JMX来监控应用程序内存使用情况以及GC正在执行的操作。

您还可以使用JVM API访问JMX正在发布的数据,请参阅GC logging flags