java – Tomcat进程在运行掉的交换空间后被Linux内核杀死;不要得到任何JVM OutOfMemory错误

前端之家收集整理的这篇文章主要介绍了java – Tomcat进程在运行掉的交换空间后被Linux内核杀死;不要得到任何JVM OutOfMemory错误前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在对tomcat服务器进行负载测试.该服务器具有10G物理内存和2G交换空间.之前,堆大小(xms和xmx)设置为3G,服务器工作正常.由于我仍然看到很多空闲的内存,性能不好,我将堆大小增加到7G,并再次进行负载测试.这次我观察到物理记忆很快被吃掉了,系统开始消耗掉交换空间.后来,tomcat在运行掉掉空间后就崩溃了.在启动tomcat时,我包括-XX:HeapDumpOnOutOfMemoryError,但是我没有得到任何堆转储.当我查看/ var / log / messages,我看到内核:内存不足:杀死进程2259( java)得分634或牺牲小孩.

要提供更多的信息,这里是我从Linux top命令中看到的,当堆大小设置为3G和7G时

xms& xmx = 3G(正常工作):

>启动tomcat之前:

Mem:  10129972k total,1135388k used,8994584k free,19832k buffers
Swap:  2097144k total,0k used,2097144k free,56008k cached

> tomcat启动后:

Mem:  10129972k total,3468208k used,6661764k free,21528k buffers
Swap:  2097144k total,143428k cached
PID  USER      PR  NI  VIRT  RES  SHR S %cpu %MEM    TIME+  COMMAND
2257 tomcat    20   0 5991m 1.9g  19m S 352.9 19.2   3:09.64 java

>启动负载10分钟后:

Mem:  10129972k total,6354756k used,3775216k free,21960k buffers
Swap:  2097144k total,144016k cached
PID  USER      PR  NI  VIRT  RES  SHR S %cpu %MEM    TIME+  COMMAND
2257 tomcat    20   0 6549m 3.3g  10m S 332.1 34.6  16:46.87 java

xms& xmx = 7G(导致tomcat崩溃):

>启动tomcat之前:

Mem:  10129972k total,1270348k used,8859624k free,98504k buffers
Swap:  2097144k total,74656k cached

> tomcat启动后:

Mem:  10129972k total,6415932k used,3714040k free,98816k buffers
Swap:  2097144k total,144008k cached
PID  USER      PR  NI  VIRT  RES  SHR S %cpu %MEM    TIME+  COMMAND
2310 tomcat    20   0  9.9g 3.5g  10m S  0.3 36.1   3:01.66 java

>起动后10分钟(在tomcat死亡之前):

Mem:  10129972k total,9960256k used,169716k free,164k buffers
Swap:  2097144k total,2095056k used,2088k free,3284k cached
PID  USER      PR  NI  VIRT  RES  SHR S %cpu %MEM    TIME+  COMMAND
2310 tomcat    20   0 10.4g 5.3g  776 S  9.8 54.6  14:42.56 java

Java和JVM版本:

Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01,mixed mode)

Tomcat版本:

6.0.36

Linux服务器:

Red Hat Enterprise Linux Server release 6.4 (Santiago)

所以我的问题是:

>为什么会发生这个问题?当JVM耗尽内存时,为什么没有抛出OutOfMemoryError?为什么直接使用互换?
>为什么顶级的RES显示java正在使用5.3G内存,有更多的内存消耗?

我一直在调查和搜索一段时间,仍然找不到这个问题的根本原因.非常感谢!

解决方法

Why would this issue happen? When JVM runs out of memory why is there no OutOfMemoryException thrown?

JVM内存不足,主机操作系统已经耗尽了与内存相关的资源,并且正在采取激烈的行动.操作系统无法知道当响应于更多内存的请求被告知“否”时,进程(在本例中为JVM)能够以有序的方式关闭.它已经很难杀死,否则整个操作系统挂起的风险很大.

无论如何,您没有看到OOME的原因是这不是OOME的情况.实际上,JVM已经被操作系统所占用的内存太多了,没有办法把它还原.这就是操作系统必须通过硬杀程序处理的问题.

And why does it go straight to using swap?

它使用交换,因为整个系统的总虚拟内存需求将不适合物理内存.这是UNIX / Linux操作系统的NORMAL行为.

Why top RES shows that java is using 5.3G memory,there’s much more memory consumed

RES号可能有点误导.他们所指的是进程当前使用的物理内存量…排除与其他进程共享或共享的东西. VIRT号码与您的问题更相关.它表示您的JVM正在使用10.4g的虚拟…这超出系统上可用的物理内存.

正如另一个答案所说,这是关于你关心你没有得到一个OOME.即使你得到一个,做任何事情也是不明智的. OOME可能对您的应用程序/容器造成附带损害,这​​些损坏很难被发现,并且难以从中恢复.这就是为什么OOME是错误而不是异常.

建议:

>不要尝试使用比具有物理内存的显存更多的虚拟内存,尤其是使用Java.当JVM运行完整的垃圾收集时,它将以随机顺序多次触及大多数VM页面.如果您明显地重新分配了内存,这可能会导致整个系统的性能下降.>增加系统的交换空间. (但这可能不会有帮助…)>不要尝试从OOME恢复.

原文链接:https://www.f2er.com/jvm/123632.html

猜你在找的JVM相关文章