有些东西一直在Ubuntu上杀死我的Java进程,任何人都知道为什么?

所以每隔几天我在Ubuntu上的java进程就会自动终止,而我不知道为什么。

我的盒子有35.84 GB的内存,当我启动我的Java过程时,我传递了-Xmx28g参数,所以它应该使用小于可用的最大RAM的方式。

我运行jstat如下:

# jstat -gccause -t `pgrep java` 60000 

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

 Time S0 S1 EOP 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”。 我没有使用应用程序服务器,但我的应用程序embedded了“简单的Web框架”。

(第二次尝试)。

假设问题在于OOM杀手,那么它已经为了让操作系统在严重的内存不足的危机中拼命尝试而杀死了你的进程。

我会得出这样的结论:

  • 你的JVM实际上使用的是远远超过28Gb; 即你有非常重要的非堆内存使用,和

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

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

或者,减少JVM的堆大小。


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

欢迎来到OOM杀手,这是一个linux内存“大全”的功能。 没有简单的配方来处理,只是谷歌,并开始阅读和武器。

虽然我不能把自己的思想放在对OOM杀手锏的简洁解释上,但我记得那个关键的调整参数叫做“swappiness”。 在我们的一个大服务器上,我们有:

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

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

你使用的是什么JVM? 和什么应用服务器? 有可能你分配太多的内存,这可能是有问题的 – 垃圾收集器可能会遇到麻烦的工作。

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

哇,你真的有28 GB的堆? 可能是你应该尝试减少它,保持在不超过我认为的RAM的50%(所以〜18 GB,甚至可能是15 GB)。 加171完整的GC是很多! 这个程序运行多久了? 在2-3天内有171次听起来很大。 btw的要点表明一个OOM之前终止 – 我认为减少堆将解决它(您可能会限制JVM扩大原生空间)。 尝试调整各种参数,例如尝试堆栈大小(-Xss),如果需要的话。 检查最大烫发大小和其他部分。 它是一个记忆问题,它可能不一定是堆。

Ubuntu有一个“看门狗”进程,当内存不足时会杀死其他进程。 查看manpage: http : //manpages.ubuntu.com/manpages/natty/man8/watchdog.8.html