有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java 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

我的问题是:

一,。为什么VIRT=8670m(在“top-p”结果中)大于Mem:8048440k,但我的应用程序仍在运行

  1. 为什么我的雄猫被内核杀死了?我看不到任何奇怪的内存(与运行时类似)

  2. 为了避免发生这种错误,我将做什么?为什么


共 (2) 个答案

  1. # 1 楼答案

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

    据我所知,在Linux中导致内核终止任务的唯一原因是out of memory killerThis article from Oracle可能更近一些,也更相关

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

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

    一些注意事项:

    1. Java使用的内存比堆多,它拥有运行VM本身的本机代码的内存
    2. Java8将permgen存储在堆之外,因此我认为它在Xmx参数的顶部添加了内存,您可能需要注意,如果运行Java8
    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实际上可以使用二进制文件。因此,文件作为只读“交换”空间,这意味着本质上加载2MB二进制文件/so将使VM大小增加2MB,但实际上不会使用所有RAM,因为它只从磁盘分页实际访问的部分