【发布时间】:2011-12-16 21:38:24
【问题描述】:
我的问题的简短描述:我使用已部署的 Wicket 应用程序启动 Tomcat。当我想关闭 tomcat 时,我收到以下错误消息:
Error occurred during initialization of VM
java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:640)
at java.lang.ref.Reference.<clinit>(Reference.java:145)
我正在运行以下设置:
- Ubuntu Linux:10.04(清醒),内核为 2.6.18-028stab094.3
- Java 版本:“1.6.0_26”Java HotSpot(TM) 64 位服务器虚拟机
- Tomcat 版本:7.0.23
- jvm_args: -Xms512m -Xmx512m -XX:MaxPermSize=205m(这些是通过 CATALINA_OPTS 添加的,仅此而已)
- 检票口 1.5.1
- Tomcat 在子域上使用 ModProxy 配置了两个虚拟主机
- 我的应用程序在 appbase 目录中部署为 ROOT.war(部署一个或两个应用程序没有区别)
- '''没有部署应用程序不会导致关闭时 OOM''',除非我弄乱了 jvm 参数
- war 的大小约为 500k,所有库都部署在 tomcat/common/lib 中(我在 conf/catalina.properties 中添加到 common.loader 的目录)
- ulimit -u -> 无限制
当我检查 Tomcat 管理器应用程序时,它会显示以下关于 JVM 内存的信息:
Free memory: 470.70 MB Total memory: 490.68 MB Max memory: 490.68 MB
(http connector) Max threads: 200 Current thread count: 6 Current thread busy: 1
'top' 或 'free -m' 类似:
Mem: 2097152k total, 1326772k used, 770380k free, 0k buffers
20029 myuser 18 0 805m 240m 11m S 0 11.7 0:19.24 java
我尝试启动 jmap 以获取堆转储,它也因 OutOfMemoryError 而失败。实际上,只要部署了我的一个或两个应用程序,任何其他 java 进程都会失败并出现相同的 OOM 错误(见顶部)。
在部署应用程序时出现问题。所以它有严重的问题。但是,该应用程序实际上运行平稳了很长一段时间。但是我在应用程序中也看到了OOM,所以我不相信冷静。
我的应用程序正在使用自定义过滤器类?会这样吗?
为了完整起见(希望如此),这是我的 common/lib 中的库列表:
activation-1.1.jar
antlr-2.7.6.jar
antlr-runtime-3.3.jar
asm-3.1.jar
asm-commons-3.1.jar
asm-tree-3.1.jar
c3p0-0.9.1.1.jar
commons-collections-3.1.jar
commons-email-1.2.jar
dependencies-provided.tgz
dom4j-1.6.1.jar
ejb3-persistence-1.0.2.GA.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-jaspic_1.0_spec-1.0.jar
geronimo-jta_1.1_spec-1.1.1.jar
hibernate-annotations-3.4.0.GA.jar
hibernate-commons-annotations-3.1.0.GA.jar
hibernate-core-3.3.0.SP1.jar
hibernate-entitymanager-3.4.0.GA.jar
hibernate-search-3.1.0.GA.jar
javassist-3.4.GA.jar
joda-time-1.6.2.jar
jta-1.1.jar
log4j-1.2.16.jar
lombok-0.9.3.jar
lucene-core-2.4.0.jar
mail-1.4.1.jar
mysql-connector-java-5.1.14.jar
persistence-api-1.0.jar
quartz-2.1.1.jar
servlet-api-2.5.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.6.1.jar
stringtemplate-4.0.2.jar
wicket-auth-roles-1.5.1.jar
wicket-core-1.5.1.jar
wicket-datetime-1.5.1.jar
wicket-extensions-1.5.1.jar
wicket-request-1.5.1.jar
wicket-util-1.5.1.jar
xml-apis-1.0.b2.jar
我很感激任何提示,甚至是推测,它们可以给我更多的想法来尝试什么。
更新:我进行了更多测试,发现此行为仅在部署我的一个或两个应用程序时发生。该行为不会发生在“空”tomcat 上(这是我弄乱 jvm args 的一个错误)
Update2:我目前正在尝试尝试在虚拟框中重现此行为,我想使用分析器对其进行调试。我仍然不相信在 2GB RAM 上运行我的设置是不可能的。
Update3 (10/01/12):我正在尝试运行 jenkins 而不是我自己的应用程序。相同的行为,所以肯定是服务器配置问题。调用 maven 时 Jenkins 作业失败,所以我什至不需要尝试下面建议的关闭黑客,因为在运行 Jenkins 时我需要第二个 java 进程。有人向我建议,因为这是一个虚拟服务器 ulimits 可能是从外部强加的,我将无法看到它们。我想我会就此提出一个新问题。谢谢大家。
Update4 (02/05/12):请参阅下面的包含提示的答案。我将在这里澄清更多:我现在 95% 确定错误发生是因为我达到了线程限制。但是,因为这是一个虚拟服务器,所以下面描述的方法无法检查这个值,因为它对 ulimit 不可见,这让我感到困惑,直到今天我才发现这是我可以看到的“numproc”值在我可以为我的虚拟服务器登录的 Parallels Power Panel 中。有 numproc 的资源警报,但直到现在我也没有看到这些。该值的硬限制为 96,我当然无法更改。 numproc 的当前值对应于我在切换“H”以查看线程后使用“top”看到的进程数。我很难找到这个,因为这个 numproc 值隐藏在面板的深处。遗憾的是,如果您想使用 apache 和 mysql 运行 Tomcat,那么 96 是一个相当低的数字。我也很难过,我什至在托管合同的小字中都找不到这个值,而且我敢说它与我的应用程序相当相关。所以我想我需要升级服务器。
感谢大家的帮助,最后每个人都帮助我找出问题所在。
【问题讨论】:
-
如果在tomcat运行时在终端运行
free -m会发生什么? -
另外,你有什么特别的 catalina_opts 吗?
-
jetty-all-server 对我来说似乎很奇怪。所有其他依赖似乎都很好,但是为什么要在 Tomcat 中嵌入码头(可能是 Wicket 需要,我不知道 Wicket)。
-
啊,感谢您对码头的提示,该提示必须来自测试。我应该删除它。
-
也许您可以使用 JVM 的 -XX:-HeapDumpOnOutOfMemoryError 选项获得堆转储:oracle.com/technetwork/java/javase/tech/…
标签: java tomcat memory-leaks wicket