记一次Java占用内存导致服务器内存不足(乌龙事件)

背景

本人有一台测试服务器,4GB内存,运行MySQL、Jenkins和2个Java应用服务。在某次Java应用的版本升级后,Jenkins由于内存不足闪退。经查,每个Java应用占用了500多MB的内存
另一台服务器,2GB内存,运行5个Java应用服务,每个Java应用只占了300多MB的内存

服务器均使用JDK 1.8,64位环境。

先说结论

Java应用和Jenkins(也是Java程序)启动时添加了-Xms256m的参数限制,导致Java应用和Jenkins至少要占用256MB的堆内存,而通过Arthas的dashboard命令查看时,发现实际仅使用80MB左右的堆内存。缺少-Xms参数后,占用内存减少。

原因

-Xms指定了Java虚拟机初始(也是最小)堆内存。
生产环境可以使用-Xms-Xmx相同的配置参数减少堆内存伸缩带来的性能消耗,但是在测试环境,尤其是内存不足时,-Xms可以指定的小一点,只要满足系统基本运行,或者保持默认(据说是系统物理内存的1/64)。

扩展

以下内容基于书和博客内容+自己分析得来,为查证官方资料,仅供参考。

从Arthas的dashboard面板中看到,Java的内存分为heapnonheap,而heap又分为eden_spacesurvivor_spaceold_gennonheap分为code_cachemetaspacecompressed_class_spacedirectmapped

eden_space:新生代堆内存,新new的对象在这里。
survivor_space:新生代堆内存,有2块。在经过gc(复制算法)后,eden_space和。survivor_sapce的存活对象会复制到另一块survivor_sapce中。
old_gen:老年代堆内存,新生代的对象在多次gc后还活着,就会转移到老年代中。老年代gc使用标记整理算法。

old_gen:存放在当前物理机环境下虚拟机字节码转换的机器码。
metaspace:存放静态数据,如Class结构、method的字节码、局部变量表、异常表、参数信息等。
compressed_class_space:是metaspace的一部分,在启用指针压缩时有效(Java每个对象都有指向Class的指针),在metaspace中单独划分一块不大于4GB(默认1GB)的内存,用来存放Class结构,原本所有指向Class结构的64位指针就都可以使用基础偏移+32位指针表示,从而可以减少内存占用。
directmapped:貌似和nio有关,没有查到相关资料。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值