9

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

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

以下是有关我的配置的一些详细信息:

  • VPS:debian-5.0-x86_64

  • 内存:2.5GB,

  • 虚拟处理器:8

  • 硬盘:60gb 硬盘 - 70% 免费

  • 雄猫 7.0

  • java-版本:

    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 参数:-Xms512m -Xmx1024m

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

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

我还通过 java.lang.Runtime 类记录 java 内存使用情况,它表明 jvm 始终使用 max200Mb 内存,并且在崩溃前没有增加。崩溃前的最后一个日志是 40 秒前,当时使用的内存是:152Mb。

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

你能告诉我为什么会崩溃吗?我怎样才能找到原因?

4

4 回答 4

1

让我们取消选择:

向处理程序发送信号 SIGTERM 时发生异常 java.lang.OutOfMemoryError - VM 可能需要强制终止。

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

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

(您可以通过查看“/var/log/messages”...或系统记录内核消息的任何位置来确认它不是 OOM 杀手。请参阅如何配置 Linux 内存不足杀手

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

一旦你有了信号的来源,你就会知道它为什么被发送的线索。


另一个值得注意的事情是OutOfMemoryError在处理 SIGTERM 时发生。这强烈暗示(对我而言)根本原因是某些东西检测到 Tomcat 使用了太多内存,并已向其发送了一个 SIGTERM 以使其(干净地)消失。我推测接下来发生的事情是 JVM 向操作系统请求更多内存(以处理 SIGTERM)并且操作系统说“不”,然后 JVM 抛出一个OutOfMemoryError. 不幸的是,JVM 现在处于无法完全退出或恢复的状态。因此它说“可能需要强制终止虚拟机”。


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

假设您准备好咬紧牙关:


1 - 除非在本机代码中做一些疯狂的事情......

于 2018-02-12T10:03:04.970 回答
0
  • 从 shell运行top,查看 Linux 声称 Java 进程占用了多少内存。

  • 检查机器中的整体内存使用情况。可能是其他进程正在消耗所有内存,从而迫使 Linux 杀死 JVM:Mysql 或 Postgress 等数据库可能是一个嫌疑犯。

  • 检查/var/log/messages崩溃前后的时间段是否有异常事件。

于 2012-06-22T12:00:41.510 回答
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 ,它非常有用,并给出了一些潜在的内存泄漏嫌疑人和支配树(即哪个对象控制了堆)这可能是一个很好的开始观点。

于 2017-08-07T10:52:51.187 回答
0

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

于 2017-09-09T16:13:47.537 回答