我抱怨我的服务器应用程序在高负载时崩溃
这是一个在Tomcat 5
中运行的网络应用
我看到线程转储,我发现有一个OutOfMemory错误
1TISIGINFO转储事件“systhrow”(00040000)详细信息
“java / lang / OutOfMemoryError”“无法创建线程:retVal -1073741830,errno 12”>收到1TIDATETIME日期:2012/07/17 at 20:03:17 1TIFILENAME> Javacore文件名:C:\ ServerApplication \ Tomcat5 \ bin \ javacore.34545719.4646464.4172.0003.txt
堆信息如下:
Maximum Java heap size : 1500m
Initial Java heap size : 256m
这是初始和最大堆大小(32位java)的配置
我也看到有可用的空闲堆空间
1STHEAPFREE Bytes of Heap Space Free: 2D19F3C0
1STHEAPALLOC Bytes of Heap Space Allocated: 5DC00000
这是750MB的免费空间,对吧?
从线程方法分析中我看到线程的数量为695
,49%
为java/lang/Object.wait(Native Method)
且39%
位于sun/misc/Unsafe.park(Native Method)
我也看到NO JAVA STACK 1%
不确定这意味着什么
0步也是死锁,2%
是Runnable。
我不确定如何解释这些信息或如何从这里继续检测根本原因 对此有何帮助?
答案 0 :(得分:9)
根据this post:
java.lang.OutOfMemoryError有两个可能的原因: 无法创建线程消息:
- 运行的线程太多,系统内部资源耗尽,无法创建新线程。
- 系统已用完本机内存以用于新线程。线程需要内部JVM结构的本机内存,即Java™ 堆栈和本机堆栈。
所以这个错误可能与内存完全无关,只是创建了太多的线程......
编辑:
由于你有695个线程,你需要695倍的堆栈大小作为内存。考虑到线程限制this post,我怀疑您正在尝试为可用虚拟内存空间创建太多线程。
答案 1 :(得分:7)
您应该使用-XX:+HeapDumpOnOutOfMemoryError
标志启动JVM。这将在生成OutOfMemoryError
时生成堆转储。
然后,正如@Steve所说,你可以使用像MAT这样的工具来分析转储并查看分配了哪些对象,以及谁保留对它们的引用。这通常可以让您了解JVM耗尽内存的原因。
答案 2 :(得分:5)
我知道你的意思,找到某个地方可能会让人感到困惑。
看看Eclipse Memory Analyzer(MAT)。它将使用JHat将程序的内存快照转储到文件中,您可以重新打开和分析该文件。
此文件的浏览器非常巧妙地概述了程序创建的所有对象,您可以查看各种级别以查找是否存在可疑内容。
附上我的评论以回答......
当您的可执行文件 webapp崩溃时,将其转储到MAT。 MAT将告诉你多次创建的对象。如果它是一个自定义对象,通常是,它很容易找到。如果没有,你可以看到它的父母,截断它,并从那里运行(抱歉图形的例子,我现在不完全专注于SO :)。
哦,我忘了提及,你可以在几个条件下多次运行程序,并且每次都进行转储。然后,您可以分析趋势的每个转储。
但在我的情况下,我应该使用什么?我有一个在Tomcat中运行的Web应用程序
抱歉,也错过了这个。如果我没弄错的话,MAT会转储JVM 进程,因此只要VM在你的盒子上运行,你就可以转储它的进程并看看发生了什么。
另一条评论突变为部分解决方案......
这比实际上变得更加困难。说真的,这很简单,在你运行MAT一两次之后就可以了解事情。运行你的应用程序,直到事情崩溃。转发它。改变些什么。运行,崩溃,转储。重复。然后,在MAT中打开转储,并比较看起来可疑的内容。
我学习这个时最棘手的部分是找到要转储的process ID - 这仍然不是太麻烦。
答案 3 :(得分:2)
类似的消息on IBM WebSphere显示此行
“无法创建线程:retVal”
表示本机OOM ,这意味着某个(进程的)线程正在尝试请求堆上的大部分内存。
上面的IBM链接有一系列步骤 - 其中一些是IBM特定的。看看。
从本机内存使用角度来看:
你可以看到的另一件事是PermGenSpace - 有多大?
此链接http://www.codingthearchitecture.com/2008/01/14/jvm_lies_the_outofmemory_myth.html建议
增加堆分配实际上会加剧这个问题!它 减少编译器和其他本机组件的净空 和玩。所以我的问题的解决方案是: 1.减少分配给JVM的堆。 2.删除因未及时释放的本机对象而导致的内存泄漏。
您是否在server.xml中为maxThreads配置了一个值?默认值为200,但您的应用似乎有695?
答案 4 :(得分:0)
遵循IBM技术说明java.lang.OutOfMemoryError while creating new threads,特别是' ulimit'命令增加默认1024的值。
[2/25/15 12:47:34:629 EST] 00000049 SystemErr R java.lang.OutOfMemoryError: Failed to create a thread: retVal -1073741830, errno 11
[2/25/15 12:47:34:630 EST] 00000049 SystemErr R at java.lang.Thread.startImpl(Native Method)
[2/25/15 12:47:34:630 EST] 00000049 SystemErr R at java.lang.Thread.start(Thread.java:936)
[2/25/15 12:47:34:630 EST] 00000049 SystemErr R at org.eclipse.osgi.framework.internal.core.InternalSystemBundle.stop(InternalSystemBundle.java:251)
[2/25/15 12:47:34:630 EST] 00000049 SystemErr R at com.ibm.ws.runtime.component.RuntimeBundleActivator.shutdownEclipse(RuntimeBundleActivator.java:54)
[2/25/15 12:47:34:630 EST] 00000049 SystemErr R at com.ibm.ws.runtime.component.ServerCollaborator$ShutdownHook$1.run(ServerCollaborator.java:878)
[2/25/15 12:47:34:630 EST] 00000049 SystemErr R at com.ibm.ws.security.auth.ContextManagerImpl.runAs(ContextManagerImpl.java:5459)
[2/25/15 12:47:34:631 EST] 00000049 SystemErr R at com.ibm.ws.security.auth.ContextManagerImpl.runAsSystem(ContextManagerImpl.java:5585)
[2/25/15 12:47:34:631 EST] 00000049 SystemErr R at com.ibm.ws.runtime.component.ServerCollaborator$ShutdownHook.run(ServerCollaborator.java:850)
[2/25/15 12:47:34:631 EST] 00000049 SystemErr R at com.ibm.ws.runtime.component.ServerCollaborator$StopAction.alarm(ServerCollaborator.java:809)
[2/25/15 12:47:34:631 EST] 00000049 SystemErr R at com.ibm.ejs.util.am._Alarm.run(_Alarm.java:133)
[2/25/15 12:47:34:631 EST] 00000049 SystemErr R at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1815)
CentOS 6.6 64位 IBM WAS 8.5.0.2 64位