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

标签 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”。我没有使用应用程序服务器,但我的应用程序嵌入了“简单网络框架”。

最佳答案

假设问题是 OOM killer ,那么它已经杀死了您的进程,以在严重的内存短缺危机中保持操作系统正常运行。

我的结论是:

  • 您的 JVM 实际上使用的内存远远超过 28Gb;也就是说,您使用了大量的非堆内存,并且

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

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

或者,减小 JVM 的堆大小。


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


系统日志确认它是 OOM killer 。

In what way does the linked syslog say so?

它是这样说的:

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)

The console says that java was killed, not that it quit.

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

If it had run out of memory it would typically throw an OutOfMemory exception, which it didn't.

如果您填满了 Java 堆,就会发生这种情况。

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

I'm running with such a huge heap because I need to store millions of objects each of which require several kilobytes of RAM.

不幸的是,您正在尝试使用比系统可用更多的 RAM。这会导致虚拟内存抖动,影响整个操作系统。

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


最后,你说:

My box has 35.84 GB of RAM ...

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

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

关于java - 在 Ubuntu 上有些东西一直在杀死我的 Java 进程,有人知道为什么吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8146152/

相关文章:

javascript - Map 的垃圾收集最近有变化吗?

java - 将 token 映射到枚举值的更好方法?

java - 我可以在 ViewPreparer 中访问 Apache Tiles 定义名称吗?

java - 重写 Xerces 实现以通过 XMLInputFactory 创建 XMLEventReader

c++ - Qt qbs 项目设置与库未找到编译错误

ubuntu - 如何在 Ubuntu 21.10 上安装 python 3.6?

java - 我正在寻找 permgen 的垃圾收集策略?

c# - MediaPlayer 中的内存泄漏

java - 如何在 Java 中将数字文件读入数组列表

c++ - alcOpenDevice : AL_INVALID_OPERATION 中的 OpenAL 软 40964