在我的工作中,我们有几个运行各种版本的 RHEL 的 SGE 集群,我们正在测试一个带有更新的 Redhat 的新集群,所有 .在旧集群(“Centos release 5.4”)上,我能够提交如下作业并且运行良好:
echo "java -Xms8G -Xmx8G -jar blah.jar ..."|qsub ... -l h_vmem=10G,virtual_free=10G ...
在新集群“CentOS release 6.2 (Final)”上,使用这些参数的作业由于内存不足而失败,我必须将 h_vmem 更改为 h_vmem=17G 才能成功。新节点的 RAM 大约是旧节点的 3 倍,在测试中我一次只放入几个作业。
在旧集群上,我将 -Xms/Xms
设置为 N
,我可以使用 N+1
左右对于 h_vmem
。在新集群上,除非将 h_vmem
设置为 2N+1
,否则我似乎会崩溃。
我写了一个很小的 perl 脚本,它所做的就是逐渐使用消耗更多的内存,并定期打印出使用的内存,直到它崩溃或达到限制。 h_vmem 参数使其在预期的内存使用情况下崩溃。
我已经尝试了多个版本的 JVM(1.6 和 1.7)。如果我省略 h_vmem
,它可以工作,但运行起来风险更大。
我用谷歌搜索了其他人看到类似问题的地方,但没有找到解决方案。
最佳答案
这里的问题似乎是与以下因素结合的问题:
- 旧集群是 RHEL5,新集群是 RHEL6
- RHEL6 包含对 glibc 的更新,它改变了 MALLOC 报告多线程程序内存使用情况的方式。
- JVM 默认包含一个多线程垃圾收集器
为了解决这个问题,我结合使用了以下方法:
- 将 MALLOC_ARENA_MAX 环境变量导出为较小的数字 (1-10),例如在作业脚本中。 IE。包括如下内容:
export MALLOC_ARENA_MAX=1
- 将 SGE 内存请求适度增加 10% 左右
- 使用
java -XX:ParallelGCThreads=1 ...
将 java GC 线程的数量显式设置为较低的数量
- 增加了 SGE 线程请求。例如。
qsub -pe pthreads 2
请注意,不清楚将 MALLOC_ARENA_MAX 一直设置为 1 是否是正确的数字,但从我的测试来看,低数字似乎效果很好。
以下是使我得出这些结论的链接:
What would cause a java process to greatly exceed the Xmx or Xss limit?
http://siddhesh.in/journal/2012/10/24/malloc-per-thread-arenas-in-glibc/
关于java - SGE h_vmem 与 java -Xmx -Xms,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18708085/