当堆栈跟踪信息里面出现OutOfMemoryError的时候,你应该很清楚发生了什么。应用程序由于没有足够的内存空间所以挂了。知道这个一般就也够了,但是对于构建和维护应用程序的人来说,要想查清楚为什么报错的话,这里倒可以再多分享一点经验。
在这篇文章里面,我们主要介绍一下不同的OutOfMemoryError具体是什么含义。我们先从最简单的例子开始,后面会有一些更有意思的话题。
Java.lang.OutOfMemoryError: Java heap space java.lang.OutOfMemoryError: PermGen space java.lang.OutOfMemoryError: GC overhead limit exceeded java.lang.OutOfMemoryError: unable to create new native thread java.lang.OutOfMemoryError: nativeGetNewTLA java.lang.OutOfMemoryError: Requested array size exceeds VM limit java.lang.OutOfMemoryError: request bytes for . Out of swap space? java.lang.OutOfMemoryError: (Native method)
下一个问题也很常见。我相信很多人在重新部署的时候 都遇见过
第三个,java.lang.OutOfMemoryError: GC overhead limit exceeded,这个问题有点特殊。这里没有提示说堆还是持久代有问题,虚拟机只是告诉你你的程序花在垃圾回收上的时间太多了,却没有什么见效。默认的话,如果你98%的时间都花在GC上并且回收了才不到2%的空间的话,虚拟机才会抛这个异常。这是一个快速失败的安全保障的很好的实践。一般来说禁用它也没有太大用处,如果需要的话你可以把-XX:-UseGCOverheadLimit加到启动脚本里。
在我们使用Plumbr解决的问题中,前三个例子覆盖了98%以上的场景。因此下面这几个你很有可能不太清楚。
java.lang.OutOfMemoryError: unable to create new native thread,如果虚拟机正在请求操作系统创建一个本地线程,而操作系统无法创建的时候,你会收到这个报错信息。这个限制的大小跟平台相关,如果你对这个限制的大小好奇的话,可以用下面这小段代码做下试验。在我的64位的Mac OSX上使用最新的JDK7,当创建的线程到2032时的就会报错。
while(true){ new Thread(new Runnable(){ public void run() { try { Thread.sleep(10000000); } catch(InterruptedException e) { } } }).start();}
联系客服