上周我偶然发现了一些有趣的问题,我注意到我们的一台生产服务器有 Apache HTTP Server超过Tomcat运行、停止、报告 HTTP 中断。
在进一步调查此问题时,似乎是由于 JVM 导致内存页面快速换出。这导致交换空间被完全填充,导致下次页面移动到交换时出现内存问题。
进一步调查,我们的一些 Linux 发行版似乎有一个 JVM 交换系数默认设置为 60%。根据一些研究,这对于高流量的 Web 服务来说似乎具有很高的值(value)。我们的交换空间设置为 2 GB。
交换详情为:
Filename Type Size Used Priority
/dev/sda3 partition 2096472 1261420 -1
From /proc/meminfo
SwapCached: 944668 kB
我们的 JVM 属性如下:
-Xmx6g -Xms4g -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:PermSize=512M -XX:MaxPermSize=1024M -XX:NewSize=2g -XX:MaxNewSize=2g -XX:ParallelGCThreads=8
服务器运行 12 GB RAM。
交换性与 JVM 的 GC 不太相配过程。因此我尝试将 swappiness 减少到 0,但这并没有改变任何东西。我们仍然会看到整个交换空间被消耗并导致 OutOfMemory 错误的情况。
如何调整 JVM 性能?
最佳答案
swappiness factor实际上是 Linux 中的系统范围设置,而不是 JVM 特定的设置。
我对某些类型的应用程序的个人经验是,它们需要关闭交换才能正常工作,就这样。虽然我不能确定您的应用程序是否属于此类别,但我已经看到尽管有足够的可用 RAM,但应用程序仍被换出。正如您所指出的,GC 和交换不能很好地混合。交换性只是操作系统的一个指示,因此它对交换量的影响可能会更大或更小,具体取决于具体情况。我的建议是尝试完全关闭交换。
为了执行此操作,您需要成为 root 或具有 sudo
访问权限。注释掉/etc/fstab
中描述swap的行,这样可以防止swap在重启后被打开。然后,为了关闭当前服务器运行的交换,请运行 swapoff -a
。如果交换区中有数据需要拉回 RAM,这可能需要几分钟的时间。然后,检查 free
输出的最后一行,确保可用交换空间的总大小为 0。之后,观察您的应用程序以确定关闭交换空间是否解决了您的问题。
关于linux - JVM 中的交换性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10853074/