我得到“Java HotSpot(TM)64位服务器VM警告:异常java.lang.OutOfMemoryError发生调度信号SIGTERM到处理程序”tomcat中的错误

时间:2012-06-19 05:49:22

标签: java tomcat7 out-of-memory jvm-crash

我在VPS上有tomcat web应用程序,有时候(大约每月一次)tomcat崩溃,catalina.out出现以下错误:

  

Java HotSpot(TM)64位服务器VM警告:异常java.lang.OutOfMemoryError将调度信号SIGTERM发送到处理程序 - 可能需要强制终止VM。

以下是我的配置的一些细节:

  • VPS:debian-5.0-x86_64

  • RAM:2.5 gb,

  • 虚拟处理器:8

  • HDD:60gb hdd - 70%免费

  • Tomcat 7.0

  • java -version:

    java version "1.6.0_18"
    OpenJDK Runtime Environment (IcedTea6 1.8.13) (6b18-1.8.13-0+squeeze1)
    OpenJDK 64-Bit Server VM (build 14.0-b16, mixed mode)
    
  • Java params:-Xms512m -Xmx1024m

我在该服务器上也有Apache-PHP。

我正在使用Munin监视服务器负载,它向我显示内存和CPU使用率始终稳定,并且在崩溃之前没有任何增加。

我也通过java.lang.Runtime类记录java内存使用情况,它显示jvm总是使用max200Mb内存,并且在崩溃之前没有增加。崩溃前的最后一个日志是40秒前,那段时间内存是:152Mb。

我的网络应用程序还运行6-7个线程,用于从不同的公共API收集数据。这些线程在tomcat启动时启动,并且它们始终以定期休眠运行。

你可以告诉我它崩溃的原因吗?我怎么能找到原因?

4 个答案:

答案 0 :(得分:1)

让我们解开这个:

  

异常java.lang.OutOfMemoryError将调度信号SIGTERM发送到处理程序 - 可能需要强制终止VM。

首先,看起来像JVM(Tomcat)进程发送了SIGTERM信号。它必须是JVM外部的东西。 JVM不向自己 1 发送信号。

所以你需要弄清楚这是做什么的。我猜第一个猜测就是OOM杀手......但是OOM杀手使用的是SIGKILL而不是SIGTERM。 JVM永远不会看到SIGKILL的到来!

(您可以通过查看" / var / log / messages" ...或系统记录内核消息的任何地方来确认它不是OOM杀手。请参阅How to Configure the Linux Out-of-Memory Killer

如果它不是OOM杀手,那么有几种方法可以找到信号的来源:

一旦你掌握了信号的来源,你就会有线索的原因。

另一个值得注意的事情是在处理SIGTERM时发生了OutOfMemoryError。这强烈暗示(对我而言)根本原因是某些东西检测到Tomcat使用了太多内存,并且发送了一个SIGTERM以使其消失(干净利落)。我猜想当时发生的事情是JVM进入操作系统要求更多的内存(处理SIGTERM),操作系统说“#34; No"”,JVM抛出{{1} }。不幸的是,JVM现在处于无法彻底退出或恢复的状态。因此它表示" VM可能需要被强行终止"。

总之。这看起来像是一个常见的Java问题的一个相当不寻常的表现。您很可能在Tomcat中运行的webapps中存在泄漏内存的错误。如果是这种情况,唯一真正的解决方案是找到并修复错误。 (增加堆大小......如果可能的话......只会解决问题。它可能会减少崩溃之间的间隔,但不太可能阻止它们。)

假设你已准备好咬紧牙关:

1 - 除非在本机代码中做某些事情......

答案 1 :(得分:0)

  • 从shell运行top并查看Linux声称的内存量 Java流程正在占据上去。

  • 检查机器的整体内存使用情况。可能就是这样 其他进程正在消耗所有内存,迫使Linux被杀死 JVM:像Mysql或Postgress这样的数据库可能是个嫌疑人。

  • 在崩溃周围的时间段内查看/var/log/messages 不寻常的事件。

答案 2 :(得分:0)

您可以编辑service.bat或service.sh文件(在deistribution的bin文件夹中找到)并将以下两个jvm参数放在

XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<PATH_TO_WRITE_DUMP>

PATH_TO_WRITE_DUMP应具有必要的权限, 一旦获得将在OutOfMemory问题的情况下生成的堆转储文件,请手动或通过某些第三方工具进行分析。 您可以在jvisualvm中加载此文件并进行一些分析,或者您可以使用eclipse的Memory-Analyzer-Plugin,它非常有用,并提供一些潜在的内存泄漏嫌疑人和支配树(即哪个对象占据了堆) 这可能是一个很好的起点。

答案 3 :(得分:0)

增加你的tomcat java启动内存,如: 设置JAVA_OPTS = -server -Xms256m -Xmx512m