Java OutOfMemoryError时如何识别问题?

时间:2014-08-27 05:31:23

标签: java out-of-memory

如何在生成java OutOfMemoryErrorstackoverflow时识别问题。由于这个原因它即将到来或为什么服务器出现故障。

例如,我正在开发一个生活在生产和UAT上的应用程序。即时生产java OutOfMemoryErrorstackoverflow

那么我们如何才能跟踪这个问题呢?是否有任何技术可以告诉我这是通过哪种代码流进行的?

请解释一下。我多次遇到这个问题。

6 个答案:

答案 0 :(得分:12)

如果你在生产中面对它并且你无法从堆栈跟踪或日志中真正推断它,你需要分析那里的内容。

让VM在OOM上转储

-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath="/tmp"

并将其用于分析。内存分析器工具(http://eclipse.org/mat/)是用于此分析的一个很好的独立程序。

答案 1 :(得分:6)

Oracle docs:- Troubleshooting Memory Leaks有详细说明:

  

当没有足够的空间来分配时,会抛出此错误   Java堆中或堆的特定区域中的对象。该   垃圾收集器无法进一步提供空间   容纳一个新对象,并且堆不能进一步扩展。

     

.....

     

诊断OutOfMemoryError的早期步骤是确定什么   错误意味着这是否意味着Java堆已满,或者是否意味着   本机堆已满?为了帮助你回答这个问题,   以下小节解释了一些可能的错误消息,   参考消息的细节部分:

     

线程“main”中的异常:java.lang.OutOfMemoryError:Java堆   空间

     

参见3.1.1详细消息:Java堆空间。

     

线程“main”中的异常:java.lang.OutOfMemoryError:PermGen space

     

参见3.1.2详细消息:PermGen空间。

     

线程“main”中的异常:java.lang.OutOfMemoryError:Requested   数组大小超过VM限制

     

请参阅3.1.3详细消息:请求的数组大小超过VM限制。

     

线程“main”中的异常:java.lang.OutOfMemoryError:request   的字节数。没有交换空间?

     

参见3.1.4详细消息:请求字节。在......之外   交换空间?。

     

线程“main”中的异常:java.lang.OutOfMemoryError:    (原生方法)

     

见3.1.5详细信息:(原生方法)。

<强>更新: -

您可以从OpenJDK download HotSpot VM源代码。如果要监视和跟踪Java堆空间的内存占用,即年轻代和旧代空间是从HotSpot VM启用详细GC。您可以在JVM启动参数中添加以下参数:

-verbose:gc –XX:+PrintGCDetails –XX:+PrintGCTimeStamps –Xloggc:<app path>/gc.log

答案 2 :(得分:2)

您可以使用 jvisualvm 在运行时管理您的流程。

您可以看到内存,堆空间,对象等......

此程序位于bin的{​​{1}}目录中。

答案 3 :(得分:1)

最好尝试在可以自由调试的地方重现问题 - 在开发服务器或本地计算机上。然后尝试调试,查找递归调用,堆大小以及正在创建的对象。不幸的是,在本地机器上重现prod env(带有它的负载等)并不总是那么容易,因此找到这种错误的根本原因可能是一个挑战。

答案 4 :(得分:1)

为Java进程提供的内存量是在启动时指定的。记忆分为不同的区域,堆和permgen是最熟悉的子区域。

通过-Xmx指定此特定进程允许的最大堆大小时, permgen的相应参数是-XX:MaxPermSize。 90%的Java应用程序似乎需要64到512 MB的permgen才能正常工作。为了找到你的极限,试验一下。

要解决此问题,您已更改了VM参数

-Xms256m -Xmx1024m -XX:+DisableExplicitGC -Dcom.sun.management.jmxremote
-XX:PermSize=256m -XX:MaxPermSize=512m

在VM参数中添加以上两行我相信你不会再遇到这个问题了

了解更多有关转到OutOfMemory

的信息

答案 5 :(得分:1)

内存配置不足: -

您的应用程序可能估计内存较少,例如您的应用程序需要2 Gb内存,但您只配置了512 Mb,因此您将获得OOME(内存不足错误)

由于Memoryleak: -

内存泄漏负责减少堆的可用内存,并且可能导致内存不足错误以便更多读取java中的内存泄漏是什么?

内存碎片: -

堆中可能存在空间但可能不连续。而堆需要压缩。重新排列内存。

过量的GC开销: -

当GC开销变得太大时,某些JVM实现(例如Oracle HotSpot)将抛出内存不足错误。此功能旨在防止几乎不间断的垃圾收集 - 例如,在垃圾收集上花费超过90%的执行时间,同时释放不到2%的内存。配置更大的堆最有可能解决此问题,但如果不是,则需要使用堆转储分析内存使用情况

分配过大的临时对象: -

尝试分配过大临时对象的程序逻辑。由于JVM无法满足请求,因此会触发内存不足错误并中止事务。这可能很难诊断,因为没有堆转储或分配分析工具会突出显示问题。您只能识别触发错误的代码区域,并且一旦发现,修复或消除问题的原因。

更多请访问我的网站

http://all-about-java-and-weblogic-server.blogspot.com/2014/02/main-causes-of-out-of-memory-errors-in.html