有什么东西在Ubuntu上不断杀死我的Java进程,有谁知道为什么?

时间:2011-11-16 03:03:02

标签: java ubuntu garbage-collection jstat

所以每隔几天我在Ubuntu上的java进程就会被自动杀死,我无法弄明白为什么。

我的盒子有35.84 GB的RAM,当我启动Java进程时,我将-xmx28g参数传递给它,所以它的使用方式应该小于可用的最大RAM。

我按如下方式运行jstat:

# jstat -gccause -t `pgrep java` 60000

在进程被杀之前,jstat的最后几行输出是:

Time     S0     S1     E      O      P       YGC   YGCT       FGC FGCT     GCT     LGCC                 GCC
14236.1  99.98   0.00  69.80  99.40  49.88   1011  232.305    11  171.041  403.347 unknown GCCause      No GC
14296.2  93.02   0.00  65.79  99.43  49.88   1015  233.000    11  171.041  404.041 unknown GCCause      No GC
14356.1  79.20   0.00  80.50  99.55  49.88   1019  233.945    11  171.041  404.986 unknown GCCause      No GC
14416.2   0.00  99.98  24.32  99.64  49.88   1024  234.945    11  171.041  405.987 unknown GCCause      No GC

这似乎是这次围绕/ var / log / syslog的内容:https://gist.github.com/1369135

除了我的java应用程序之外,这台服务器上什么都没有运行。发生了什么事?

编辑:我正在运行java版本1.6.0_20,我在启动时传递给java的唯一值得注意的参数是“-server -Xmx28g”。我没有使用应用程序服务器,但我的应用程序嵌入了“简单的Web框架”。

5 个答案:

答案 0 :(得分:7)

假设这个问题是OOM的杀手,那么它已经扼杀了你的进程,迫切希望让操作系统在严重的内存短缺危机中保持运作。

我会得出结论:

  • 您的JVM实际上使用的功率远远超过28Gb;即你有非常大的非堆内存使用量,

  • 操作系统未配置足够的交换空间。

我会尝试添加更多的交换空间,以便操作系统可以在紧急情况下更换部分应用程序。

或者,减少JVM的堆大小。


请注意,“ - Xmx ...”设置最大堆大小,而不是JVM可以使用的最大内存量。 JVM将一些东西放在堆外,包括用于线程堆栈的内存和应用程序正在使用的内存映射文件。


系统日志确认它是工作中的OOM杀手。

  

链接的syslog以什么方式这样说?

它说:

Nov 15 13:53:49 ip-10-71-94-36 kernel: [3707038.606133] Out of memory: kill process 6368 (run.sh) score 4747288 or a child
Nov 15 13:53:49 ip-10-71-94-36 kernel: [3707038.606146] Killed process 9359 (java)
  

控制台说java被杀了,而不是它退出了。

正确。它被操作系统的OOM杀手杀死了。

  

如果内存不足,通常会​​抛出OutOfMemory异常,但事实并非如此。

如果你已经填满了Java堆,那就会发生这种情况。

这不是这里发生的事情。实际问题是没有足够的物理RAM来容纳Java堆。 OOM杀手处理它......

  

我正在运行如此庞大的堆,因为我需要存储数百万个对象,每个对象需要几千字节的RAM。

不幸的是,您尝试使用比系统上可用的RAM更多的RAM。这导致虚拟内存崩溃,影响整个操作系统。

当系统开始严重崩溃时,OOM杀手(而不是JVM)会将您的Java进程识别为问题的原因。然后它(用SIGKILL)杀死它以保护系统的其余部分。如果没有,则存在整个系统完全锁定并需要重新启动的风险。


最后,你说:

  

我的盒子有35.84 GB的RAM ......

这是一个奇怪的价值。 32 GiB是34,359,738,368字节或34.35 GB。

但基于此和观察到的行为,我怀疑这是可用的虚拟内存而不是物理RAM。或者,您的“盒子”可以是在虚拟机管理程序级别启用RAM overcommit的虚拟机。

答案 1 :(得分:6)

欢迎来到OOM杀手,这是一个linux'功能',是各地大内存应用程序的祸根。没有简单的方法可以处理,只需google for it并开始阅读和武器。

虽然我无法用精神上的手指对OOM杀手的诡计进行简明扼要的解释,但我记得关键的调整参数叫做'swappiness'。在我们的一台大型服务器上,我们有:

/etc/sysctl.conf:vm.swappiness=20

阅读http://www.gentooexperimental.org/~patrick/weblog/archives/2009-11.html

答案 2 :(得分:3)

您使用的JVM是什么?什么应用服务器?您可能会分配太多内存,这可能会有问题 - 垃圾收集器可能无法完成其工作。

我不确定这是不是你的情况,但我发现了一篇非常有趣的this文章,解释了Linux过度使用内存的方式。

答案 3 :(得分:1)

哇,你真的可以拥有28 GB的堆吗?!也许你应该尝试减少它,保持不超过我认为的RAM的50%(所以~18 GB,甚至可能是15 GB)。加上171个Full GC很多!这个应用运行多久了?在2-3天的171听起来很大。顺便说一句,gist在终止前表示OOM - 我认为减少堆会修复它(你可能会限制JVM扩展本机空间)。尝试调整各种参数,如果需要,尝试堆栈大小(-Xss)。检查最大烫发尺寸和其他部分。它是一个内存问题,它可能不一定是堆。

答案 4 :(得分:1)

Ubuntu有一个“监视程序”进程,当内存不足时会杀死其他进程。 请参阅联机帮助页: http://manpages.ubuntu.com/manpages/natty/man8/watchdog.8.html