1

我的 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. 为避免此错误发生,我该怎么办?为什么?

4

2 回答 2

3

我所知道的唯一会导致内核在 Linux 中终止任务的是内存不足的杀手来自 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+swap 大小。我记得在具有 256MB RAM 的无交换嵌入式系统上运行 Java 并看到 500MB 的内存使用并感到惊讶。一些原因:
    1. 在 Linux 中,您可以分配内存,但直到您写入它才真正使用它
    2. 内存映射文件(可能还有共享内存段之类的东西)计入此限制。我相信 Java 会将所有 jar 文件作为内存映射文件打开,因此包含在该 virt 大小中的是类路径上的所有 jar,包括 80MB 左右的 rt.jar。
    3. 共享对象可能计入 VIRT 但只占用一次空间(即为许多进程加载的一个副本)
    4. 我听说过,但我现在找不到参考资料,Linux 实际上可以使用二进制文件/.so 文件作为只读“交换”空间,这意味着本质上加载 2MB 二进制文件/so 将使您的 VM 大小增加 2MB但实际上并未使用所有这些 RAM,因为它仅从磁盘中分页实际访问的部分。
于 2014-08-27T02:49:00.447 回答
1
  1. Linux OS 有OOM 机制,当OS 内存不足时。OOM 将终止 cost max memory 程序(在大多数情况下,Linux Out Of Memory Management)。显然你的tomcat拥有最大内存。
  2. 怎么解决?以我的经验,你必须观察操作系统的内存使用情况,你可以使用top命令来观察,找到合适的进程。同时可以使用jvisualvm来观察tomcat的使用内存情况。
于 2014-08-27T02:32:13.097 回答