10

我抱怨我的服务器应用程序在高负载时崩溃。
它是一个运行在Tomcat 5.
我看到了线程转储,并且看到了 OutOfMemory 错误

1TISIGINFO 转储事件“systhrow”(00040000)详细信息
“java/lang/OutOfMemoryError”“无法创建线程:retVal -1073741830,errno 12”>收到 1TIDATETIME 日期:2012/07/17 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)看到 这不确定这意味着什么。 0 踩死锁并且是可运行的。 39%sun/misc/Unsafe.park(Native Method)
NO JAVA STACK 1%
2%

我不确定如何解释这些信息或如何从这里继续检测根本原因。
对此有什么帮助吗?

4

5 回答 5

9

根据这篇文章

java.lang.OutOfMemoryError: Failed to create a thread 消息有两个可能的原因:

  • 运行的线程过多,系统内部资源不足,无法创建新线程。
  • 系统已用完用于新线程的本机内存。线程需要用于内部 JVM 结构的本机内存、Java™ 堆栈和本机堆栈。

所以这个错误很可能与内存完全无关,只是创建了太多线程......

编辑:

由于您有 695 个线程,因此您需要 695 倍的堆栈大小作为内存。考虑到这篇关于线程限制的帖子,我怀疑您试图为可用的虚拟内存空间创建太多线程。

于 2012-07-27T08:21:18.103 回答
7

-XX:+HeapDumpOnOutOfMemoryError您应该使用该标志启动 JVM 。这将在生成时产生堆转储OutOfMemoryError

然后,正如@Steve 所说,您可以使用 MAT 之类的工具来分析转储并查看分配了哪些对象,以及谁在保留对它们的引用。这通常会让您了解 JVM 耗尽内存的原因。

于 2012-07-27T07:03:42.570 回答
5

我知道你的意思,找到开始的地方可能会令人困惑。

看看Eclipse 内存分析器(MAT)。它将使用 JHat 将程序的内存快照转储到文件中,您可以重新打开和分析该文件。

该文件的浏览器非常整齐地概述了程序创建的所有对象,您可以查看各个级别以查找是否有可疑之处。


附加我的评论以回答...

当您的可执行web 应用程序崩溃时,将其转储到 MAT。MAT 会多次告诉您正在创建什么对象。如果它是自定义对象,而且通常是,那么很容易找到。如果没有,您可以看到它的父级,将其截肢,然后从那里运球(对不起,对于图形示例,我目前并不完全专注于 SO :)。

哦,我忘了说,你可以在几种情况下多次运行程序,每次都进行转储。然后,您可以分析每个转储的趋势。


但就我而言,我应该使用什么?我有一个在 Tomcat 中运行的 Web 应用程序

不好意思,也错过了。如果我没记错的话,MAT 会转储 JVM进程,因此只要 VM 在您的机器上运行,您就可以转储其进程并查看发生了什么。


另一条评论变成了部分解决方案......

这变得比实际上更困难。说真的,这很容易,只要你运行 MAT 一次或两次就能掌握窍门。运行您的应用程序,直到事情崩溃。倾倒它。改变些什么。运行,崩溃,转储。重复。然后,打开 MAT 中的转储,并比较看起来可疑的内容。

当我学习这一点时,最棘手的部分是找到要转储的进程 ID - 这仍然不是太让人麻木。

于 2012-07-27T06:50:37.967 回答
2

IBM WebSphere 上的类似消息显示了这一行

“创建线程失败:retVal”

作为本机 OOM的指示,这意味着(进程的)某个线程正在尝试请求堆上的大部分内存。

上面的 IBM 链接有一系列步骤 - 其中一些是 IBM 特定的。看一看。

从本机内存使用的角度来看:

  • 最大 Java 堆设置
  • JDBC 驱动程序
  • JNI 代码或本机库
  • 未使用类的垃圾收集。确保未设置 -Xnoclassgc。
  • 线程池设置(固定大小的线程池)
  • 太多的类加载器等,但这些不是很常见。
  • 来自 javacores 的类/类加载器的数量。

您可以查看的另一件事是 PermGenSpace - 它有多大?

此链接http://www.codingthearchitecture.com/2008/01/14/jvm_lies_the_outofmemory_myth.html建议

增加堆分配实际上加剧了这个问题!它减少了编译器和其他本地组件必须使用的空间。所以我的问题的解决方案是:1.减少分配给JVM的堆。2. 消除原生对象未及时释放造成的内存泄漏。

您是否还在 server.xml 中为 maxThreads 配置了一个值?默认值为 200 但您的应用似乎有 695 ?

于 2012-07-27T08:33:21.477 回答
0

使固定

在创建新线程时遵循 IBM 技术说明java.lang.OutOfMemoryError,特别是使用 '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 位

参考

于 2015-02-25T04:54:16.807 回答