1

我在具有 2GB RAM 的 debian-lenny x64 服务器上运行带有 apache 2.2 和 mod_jk 1.2.26 的 tomcat 7。
我的服务器有一个奇怪的问题:每隔几个小时,有时(在负载下)每隔几分钟,我的 tomcat ajp-connector 就会因内存泄漏错误而暂停,但似乎这个错误也会影响系统的其他一些部分(例如其他一些正在运行的应用程序也停止工作)&我必须重新启动服务器才能解决问题一段时间。
我已经检查了 catalina.out 好几天了,但似乎在暂停 ajp 并显示此消息之前没有唯一的错误模式:

INFO: Pausing ProtocolHandler ["ajp-bio-8009"]

有时在暂停前会出现此消息:

Exception in thread "ajp-bio-8009-Acceptor-0" java.lang.OutOfMemoryError: unable to create new native thread
    at java.lang.Thread.start0(Native Method)
    at java.lang.Thread.start(Thread.java:597)...

有时这个:

INFO: Reloading Context with name [] has started
Exception in thread "ContainerBackgroundProcessor[StandardEngine[Catalina]]" java.lang.OutOfMemoryError: unable to create new native thread
    at java.lang.Thread.start0(Native Method)
    at java.lang.Thread.start(Thread.java:597)
    at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5482)
    at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:230)
    at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3847)
    at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:424)
    at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1214)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1400)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1410)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1410)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1389)
    at java.lang.Thread.run(Thread.java:619)
java.sql.SQLException: null,  message from server: "Can't create a new thread (errno 11); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug"...

& 有时是与程序的其他部分相关的输出消息。
我检查了我的应用程序源代码,我猜它不会导致问题,我还使用 jConsole 检查了内存使用情况。流浪点是,当服务器出现故障时,在堆和非堆 jvm 内存空间上都会显示大量可用内存。正如我之前所说,在服务器崩溃后,许多其他应用程序也失败了,当我想重新启动它们时,它会给出一个资源暂时不可用的消息(我还检查了我的 limits.conf 文件)。
所以我真的很困惑这个严重的问题很多天了,我真的不知道了。所以,任何人都可以给我任何建议来解决这个复杂的& 未知问题???
这个错误最可能的原因是什么?

4

3 回答 3

0

使用 jvisualvm 检查 jvm 的堆使用情况。如果您看到它在一段时间内缓慢攀升,那就是内存泄漏。有时内存泄漏是短期的,最终会被清除,然后重新开始。

如果您看到锯齿模式,请在锯齿峰值附近进行堆转储,否则在 jvm 运行足够长的时间以产生 OOM 错误的高风险后进行堆转储。然后将该 .hprof 文件复制到另一台机器并使用 Eclipse MAT(内存分析工具)打开它并找出可能的罪魁祸首。您仍然需要花一些时间来关注数据结构中的 refs,并阅读一些 Javadocs 以找出正在使用的 Hashmap 或 List 正在失控的原因。排序选项对于关注最可能出现的问题区域也很有用。

没有简单的答案。

请注意,SUN jvm 还包含一个命令行工具,可以触发 heapdump。如果你有一个很好的分析器也可以使用,因为内存泄漏通常出现在一段经常执行的代码中,因此会在分析器中显示为热点。

于 2012-11-22T08:31:56.557 回答
0

我终于找到了问题所在:实际上并不是内存泄漏,而是 VPS 允许线程数的限制导致了问题。我的服务器是一个 Xen vps,默认限制为 256 个线程,所以当它达到允许的最大线程数时,主管被杀死了一些正在运行的线程(这是停止我的一些正在运行的进程的原因)。通过将允许的线程数增加到512,问题完全解决了(当然如果我在tomcat设置中增加maxThreads,很明显问题会再次出现)。

于 2012-11-29T08:00:57.450 回答
0

您对进程数量的限制是多少?

使用 uname -a 检查它们并检查最大进程数。如果是 1024,则增加它。

此外,检查您用来启动它的用户的相同内容(例如,如果您使用nobody 用户作为您的东西,请运行 su -c "ulimit -a" -s /bin/sh nobody 以查看实际内容用户视为限制)。那应该向您表明一个问题(几天前就遇到过,完全错过了检查)。

在这种情况开始发生的那一刻,您还可以使用“ps -eLf | wc -l”计算该用户的所有正在运行的线程和进程(或者甚至更好地使用 rrdtool 或其他东西来监视它),这将使您返回简单系统上运行的所有进程和线程的计数。此信息以及针对所有特定用户的限制应该可以解决您的问题。

于 2012-11-17T23:17:36.467 回答