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