什么会导致Java进程大大超过Xmx或Xss限制?

14

我运行了7个不同的Java守护进程(全部在3台不同的服务器上)。Java命令行使用了-Xmx2048m和-Xss1024k。在这些3台服务器上,所有21个进程在top和atop中显示的VIRT大小都略小于2.5GB。根据每个守护程序的不同,RES大小从300MB到1.9GB不等。

这一切都符合预期。

现在引入了一台新服务器。它拥有更快的CPU、更多的RAM(16GB而不是8GB),稍微更新的Java(旧服务器上为1.6.0_10-b33,新服务器上为1.6.0_31-b04)。这两个系统(和JVM)都是64位的。

我将其中的2个守护进程迁移到了新服务器。在新服务器上,给定相同的任务,这两个守护进程消耗的CPU要多得多(约等于一个核心),并且完成的工作量要少。这些守护进程从旧系统上的5110个处理器迁移到新系统上的5620个处理器。

一个守护进程报告使用了几乎完整的额外CPU使用率(GC线程??),并显示5GB VIRT和2GB RES,另一个守护进程则显示10.5GB VIRT和2GB RES。

有什么想法会导致Java忽略(或表现为忽略)内存限制吗?


VIRT是虚拟内存,与堆空间没有直接关系。我建议阅读这个问题的答案:https://dev59.com/HVTTa4cB1Zd3GeqPoQIx - Matt Ball
你在新机器上尝试使用相同版本的Java了吗?它们的位数都一样吗? - Dave Newton
Xmx 不是指定 JVM 的内存使用量,而是指定堆分配池的最大大小,这只是 JVM 使用的内存池之一。 - skaffman
GC1,更大的Perm空间。(猜测很野,但适合版本。)您可以尝试强制虚拟机使用另一个GC。 - esej
我建议你向左转,检查新服务器的所有DNS条目是否与主机名匹配,并设置反向IP查找。 - Jonathan
显示剩余2条评论
1个回答

14

原来这是glibc的问题。

简短的回答是:

export MALLOC_ARENA_MAX=1

这将进程占用内存(在top中的VIRT)减少了多达5倍。回到了CentOS 5中看到的水平。

glibc的最新版本有一个新功能"每个线程的内存池":

http://www.centos.org/docs/5/html/5.4/Technical_Notes/glibc.html

1.71.1日志部分的最后一项讨论了它(并引用了一个非公开的错误……)


5
为了获得一些多线程内存方面的好处,您可能希望将MALLOC_ARENA_MAX设置为4而不是1。参见此链接:issues.apache.org/jira/browse/HADOOP-7154 - michael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接