简体   繁体   English

Java 8 JVM挂起,但内存不足时不会崩溃/堆转储

[英]Java 8 JVM hangs, but does not crash/ heap dump when out of memory

When running out of memory, Java 8 running Tomcat 8 never stops after a heap dump. 当内存不足时,运行Tomcat 8的Java 8不会在堆转储后停止。 Instead it just hangs as it max out memory. 相反,它只是因为最大内存而挂起。 The server becomes very slow and non-responsive because of extensive GC as it slowly approaches max memory. 由于大量GC导致服务器缓慢接近最大内存,因此服务器变得非常缓慢且无响应。 The memory graph in JConsole flat lines after hitting max. 达到最大值后,JConsole扁平线中的内存图。 64 bit linux/ java version "1.8.0_102"/ Tomcat 8. Jconsole 64位linux / java版本“ 1.8.0_102” / Tomcat 8. Jconsole

I have set -XX:HeapDumpOnOutOfMemoryError and -XX:HeapDumpPath. 我设置了-XX:HeapDumpOnOutOfMemoryError和-XX:HeapDumpPath。 Anyone know how to force heap dump instead of JVM getting into unresponsive/ very slow response mode? 有谁知道如何强制堆转储而不是让JVM进入无响应/响应速度很慢的模式?

Anyone know how to force heap dump instead of JVM getting into unresponsive/ very slow response mode? 有谁知道如何强制堆转储而不是让JVM进入无响应/响应速度很慢的模式?

You need to use -XX:+UseGCOverheadLimit . 您需要使用-XX:+UseGCOverheadLimit This tells the GC to throw an OOME (or dump the heap if you have configured that) when the percentage time spent garbage collecting gets too high. 当垃圾收集所花费的时间百分比过高时,这会告诉GC抛出OOME(或者,如果配置了,则抛出堆)。 This should be enabled by default for a recent JVM ... but you might have disabled it. 默认情况下,应为最近的JVM启用此功能...但是您可能已禁用它。

You can adjust the "overheads" thresholds for the collector giving up using -XX:GCTimeLimit=... and -XX:GCHeapFreeLimit=... ; 您可以使用-XX:GCTimeLimit=...-XX:GCHeapFreeLimit=...来调整收集器放弃的“开销”阈值; see https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gc-ergonomics.html 参见https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gc-ergonomics.html

The effect of "overhead" limits is that your application gets the GC failures earlier. “开销”限制的作用是使您的应用程序更早地出现GC故障。 Hopefully, this avoids the "death spiral" effect as the GC uses a larger and larger proportion of time to collect smaller and smaller amounts of actual garbage. 希望这可以避免“死亡螺旋”效应,因为GC使用越来越多的时间来收集越来越少的实际垃圾。

The other possibility is that your JVM is taking a very long time to dump the heap. 另一种可能性是您的JVM需要很长时间来转储堆。 That might occur if the real problem is that your JVM is causing virtual memory thrashing because Java's memory usage is significantly greater than the amount of physical memory. 如果真正的问题是您的JVM导致虚拟内存崩溃,则可能发生这种情况,因为Java的内存使用量明显大于物理内存量。

jmap is the utility that will create a heap dump for any running jvm. jmap是可为任何正在运行的jvm创建堆转储的实用程序。 This will allow you to create a heap dump before a crash 这将允许您在崩溃之前创建堆转储

https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr014.html https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr014.html

It will be a matter of timing, though, to know when you should create it. 但是,知道何时创建它只是时间问题。 You can take subsequent heaps and use tools to compare the heaps. 您可以获取后续堆,并使用工具比较堆。 I highly recommend Eclipse Memory Access Tool and it's dominator tree view to identify potential memory issues ( https://www.eclipse.org/mat/ ) 我强烈建议使用Eclipse Memory Access Tool及其主导树视图来识别潜在的内存问题( https://www.eclipse.org/mat/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM