例如,我正在开发一个应用程序,该应用程序在生产环境和 UAT 上运行。突然,在生产环境中遇到了 Java OutOfMemoryError 或 StackOverflow 错误。
那么,我们如何跟踪这个问题呢?导致这个问题的原因是什么?有没有一种技术可以告诉我是哪段代码流导致了这个问题?
请解释一下,我遇到过很多次这样的问题。
如果你在生产环境中遇到这个问题,而且通过堆栈跟踪或日志无法真正推断出原因,那么你需要分析其中的内容。
使虚拟机在OOM时转储
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath="/tmp"
并将其用于分析。 内存分析器工具 (http://eclipse.org/mat/) 是进行此分析的不错独立程序。
HeapDumpOnOutOfMemoryError
标志必须以-XX:+
为前缀,而不是-XX:-
(某些文档有误)。我正在编辑您的答案以修正此问题。 - Eli AcherkanOracle文档:-内存泄漏故障排除 对此有详细的解释:
这个错误是在Java堆中或堆的特定区域没有足够的空间来分配一个对象时抛出的。垃圾回收器无法提供进一步的空间以容纳新对象,而堆也无法进一步扩展。更新:
你可以从OpenJDK 下载 HotSpot VM源代码。如果你想要监控和跟踪Java堆空间的内存占用情况,即年轻代和老年代空间,就需要在HotSpot VM中启用详细GC。你可以在JVM启动参数中添加以下参数:
-verbose:gc –XX:+PrintGCDetails –XX:+PrintGCTimeStamps –Xloggc:<app path>/gc.log
对此有详细的解释
- user3414693您可以使用 jvisualvm
在运行时管理您的进程。
您可以查看内存、堆空间、对象等等...
这个程序位于您的 JDK
的 bin
目录中。
-Xms256m -Xmx1024m -XX:+DisableExplicitGC -Dcom.sun.management.jmxremote
-XX:PermSize=256m -XX:MaxPermSize=512m
在VM参数中添加上述两行,我相信您将不再面临这个问题。
要了解更多,请访问OutOfMemory。
低内存配置 :-
可能您为应用程序估计的内存较少,例如您的应用程序需要2 GB的内存,但您只配置了512 MB,因此您将收到OOME(内存不足错误)
由于内存泄漏:
内存泄漏会降低堆可用内存,并可能导致内存不足错误。要了解更多信息,请阅读《Java中的内存泄漏是什么?》
内存碎片化:
堆中可能有空间,但它可能不是连续的。堆需要压缩。重新排列其内存。
过度GC开销:
某些JVM实现,例如Oracle HotSpot,在GC开销过大时会抛出内存不足错误。这个功能旨在防止几乎不断进行垃圾回收 - 例如,在释放不到2%的内存的情况下花费超过90%的执行时间进行垃圾回收。配置更大的堆最有可能解决此问题,但如果无法解决,则需要使用堆转储分析内存使用情况。
分配过大的临时对象:
程序逻辑试图分配过大的临时对象。由于JVM无法满足请求,将触发内存不足错误并中止事务。这可能很难诊断,因为没有堆转储或分配分析工具会突出显示问题。您只能确定触发错误的代码区域,并一旦发现问题的原因,修复或删除其原因。