Tomcat被内核杀死了

时间:2014-08-27 02:23:29

标签: java linux embedded-tomcat-7

我的tomcat突然自动关闭。我检查了日志文件,发现它被杀死了消息:

kernel: Killed process 17420, UID 0, (java) total-vm:8695172kB, anon-rss:4389088kB, file-rss:20kB

我运行tomcat的设置是-Xms2048m -Xmx4096m -XX:NewSize=256m -XX:MaxNewSize=512m -XX:PermSize=256m -XX:MaxPermSize=1024m

我的系统运行命令" free -m"是:

     total       used       free     shared    buffers     cached
Mem: 7859 7713 146 0 97 1600 
-/+ buffers/cache: 6015 1844 Swap: 0 0 0

我使用" top -p"监控程序,结果如下

Cpu(s): 0.1%us, 0.0%sy, 0.0%ni, 99.9%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 8048440k total, 7900616k used, 147824k free, 100208k buffers Swap: 0k total, 0k used, 0k free, 1640888k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4473 root 20 0 8670m 2.5g 6568 S 0.0 32.6 71:07.84 java

我的问题是:

1.为什么VIRT = 8670m(" top -p"结果)大于Mem:8048440k,但我的应用程序仍在运行?

  1. 为什么我的tomcat被内核杀死?我没有看到任何奇怪的记忆(它与它的运行时相似)

  2. 为避免此错误发生,我该怎么办?为什么?

2 个答案:

答案 0 :(得分:3)

我所知道的唯一导致内核在Linux中杀死任务的是out of memory killerThis article from Oracle可能有点近期和相关。

解决方案取决于系统上运行的其他内容。根据您的展示,您的可用内存不到2GB,但您的Java堆最大值大约为4GB。我们不知道的是,在您拍摄快照时,Java堆有多大。如果它的初始2GB,那么你可能会接近极限。此外,根据您的格式,您没有可用作后备的交换空间。

如果系统上有任何其他重要进程,则需要考虑其最大内存使用量。简短的回答是尝试减少Xmx和MaxPermSize,如果可能的话,你必须分析你的负载,看看是否可能或者会导致不合理的GC CPU使用。

一些注意事项:

  1. Java使用的内存多于堆,它具有运行VM本身的本机代码的内存。
  2. Java 8在堆外部存储permgen,所以我相信它会在Xmx参数之上添加内存,您可能需要注意,如果运行Java 8。
  3. 当您减少内存限制时,您将达到3个范围:
    1. 远远超出实际要求:没有明显差异
    2. 非常接近实际要求:服务器冻结/停止响应并使用100%CPU(GC开销)
    3. 以下实际要求:OutOfMemoryErrors
  4. 根据您的第一个问题,进程的VM大小可能超过RAM +交换大小。我记得在具有256MB RAM的无交换嵌入式系统上运行Java并且看到500MB的内存使用并且感到惊讶。一些原因:
    1. 在Linux中,您可以分配内存,但在您写入内容之前它实际上并未使用
    2. 内存映射文件(可能还有共享内存段等)计入此限制。我相信Java会打开所有jar文件作为内存映射文件,因此包含在virt类型中的是类路径中的所有jar文件,包括80MB左右的rt.jar。
    3. 共享对象可能会计入VIRT,但只占用一次空间(即为多个进程加载一个副本)
    4. 我听说过,但我现在找不到引用,Linux实际上可以使用二进制文件/ .so文件作为只读" swap"空间,意味着实际上加载2MB二进制文件将使您的VM大小增加2MB,但实际上不会使用所有RAM,因为它只从磁盘中访问实际访问的部分。

答案 1 :(得分:1)

  1. 当操作系统的内存不足时,Linux操作系统有一个OOM机制。 OOM将终止成本最大内存程序(在大多数情况下,Linux Out Of Memory Management)。显然你的tomcat拥有最大内存。
  2. 如何解决?根据我的经验,您必须观察操作系统的内存使用情况,您可以使用top命令进行观察,并找到正确的进程。同时,您可以使用jvisualvm来观察tomcat的使用记忆。