OOMKiller 导致托管 Java 的机器无响应

OOMKiller 导致托管 Java 的机器无响应

我在私有 vSphere 云中运行两台服务器,均运行 JBoss 和 Tomcat。

  • 机器 8 - RHEL5.3,3GB“物理”内存,1GB交换空间
  • 机器 25 - RHEL4.6,2GB“物理”内存,1GB交换空间

每隔一段时间,机器 8 就会变得没有响应,OOMKiller 会有效地接管机器。通过 vSphere 管理控制台重新启动是唯一的选择。

我们一直认为这是 Java 应用程序的限制(Xmx 等)设置过高造成的。因此,在最近一次重启后,我们借此机会降低了 JVM 的内存限制,并设置了一些记录某些信息的脚本。

这一次,问题似乎在两台机器上都发生了,尽管针对该问题的特定日志仅出现在机器 8 上。

有趣的是,交换使用量在一分钟内翻倍,但 Java 应用程序的使用量却没有。遗憾的是,我们的日志记录集中在 JVM 上,所以我们不知道究竟是什么请求了所有这些内存。

以下是机器停止响应之前的内存使用情况日志(根据各个 JVM 的 Top 信息日志重新构建):

Time        Load Average    Phys Used    Virt Used
00:19:23    1,01            3016868      380872
00:20:27    3,44            3025136      435216
00:20:32    3,24            3029548      475548
00:21:37    3,51            3023888      864404
00:21:43    3,39            3030808      889608

因此,虚拟内存使用量在 2.5 分钟内从 380 MB 增加到 889 MB。

我知道问题,但不太清楚是否是同一个问题——在我们的机器上 Java 的使用似乎并没有不合理,而最受此问题困扰的机器是 RHEL5.3。

我们尚未vm.lower_zone_protection按照链接问题中的建议激活该选项。

有人有什么建议或解释吗?

此外,机器 25 也发生故障是巧合吗,还是 vSphere 中存在导致它们都做出这种反应的情况?

答案1

导致问题的是 JVM。基本上,JVM 会“预先分配”它想要的所有内存,但内核实际上只在 JVM 真正需要时才“提供”内存。因此,您可以很快陷入您所描述的情况(交换使用率飙升,OOM 杀手肆虐),而没有任何“明显”使用内存的东西——因为原则上,内存已经“在使用中”。

解决方案包括调整 JVM 以减少使用过多的内存,关闭过度使用(这不是一个好主意,原因我已经了解过)之前解释过)、提供更多交换空间(机器会慢得像爬行一样,但不会死机,让您有机会进入并“实时”检查问题),或者只是为虚拟机提供更多内存。这足够便宜了。

相关内容