本篇介绍 O2OA 服务器运行时的 JVM 堆内存设置与释放问题。文章说明了启动脚本中堆最小值与上限的参数含义,并结合实际占用情况,说明在内存紧张的环境里可调整空闲堆比例来减少预留空间;同时比较了不同垃圾回收器归还内存的表现,给出切换回收器的做法。文中还给出了查看实际内存占用的命令示例,便于在容器环境中对照验证调优效果。
o2server 启动后一般占用大约 4G~6G 内存,启动脚本中默认通过 -Xms2g 把 heap(堆)最小值限定为 2G,上限则可用 -Xmx 调整。
-Xms2g:设置 JVM 初始堆内存为2g.此值可以设置与-Xmx 相同,以避免每次垃圾回收完成后 JVM 重新分配内存。
-Xmx5g:设置 JVM 最大堆内存为5g.如果不设置默认情况下为物理内存的1/4.
下面我们看一下 o2server 实际内存占用.通过 top 命令可以看到运行中 o2server 的 pid 号为:15167
实际占用内存4.014g.但是这4g 内存中有很大一部分处于空闲状态。
通过命令:
/data/o2server/jvm/linux_java11/bin/jhsdb jmap --heap --pid 15167
我们可以查看到内存占用情况如图:
实际堆占用内存2458M,使用1486M,空闲971M
实际占用内存至少有40%是处于 free 状态预留的。
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
其中 MinHeapFreeRatio = 40表示如果 free 的内存比上现在占用的内存,也就是空闲比例小于40,那么 jvm 将向系统申请一些内存以至少达到40%的比例---扩容。
其中 MaxHeapFreeRatio = 70表示如果 free 的内存比上现在占用的内存,也就是空闲比例大于70,那么 jvm 将减少占用的内存,并将减少占用的内存释放操作系统--缩容。
设置
-XX:MaxHeapFreeRatio,-XX:MinHeapFreeRatio
在内存较紧张的场景(例如 docker 环境)中,可以通过设置 -XX:MaxHeapFreeRatio 与 -XX:MinHeapFreeRatio,减少 jvm 预留的空间:
````shell
-XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=25
````
当空闲内存大于25%时进行缩容,当空闲内存小于10时进行扩容.减少预留的 free 空间。
再次运行 jhsdb 查看
设置生效后,实际内存并不会立即释放回操作系统,仍占用在预留空间中;java11 默认使用 G1GC,jvm 不一定会马上归还内存,此时可将 GC 改为 serialGC(-XX:+UseSerialGC)。
可以看到 jvm 立即归还了内存;不同 GC 的表现并不一致,G1GC 也会逐步把内存归还给操作系统。
在 Java12 中可以使用 ShenandoahGC(-XX:+UseShenandoahGC),将可释放的内存更快归还给操作系统。
各种常用的 GC 中只有 ParallelGC 不具备内存伸缩能力.而其他的 GC.例如:Serial.CMS,G1,ShenandoahGC 都具备内存伸缩能力.需要说明的是,具备伸缩能力的前提是 Xms 小于 Xmx,其伸缩能力上限由 Xmx 限制,伸缩能力下限由 Xms 限制.伸缩的比例由 MaxHeapFreeRatio 和 MinHeapFreeRatio 控制,其中 Serial 和 CMS 的效果一般,G1需要借助 FGC 才能将不再使用的内存归还给操作系统.至于 JDK12带来的 ShenandoahGC,效果非常好,而且不需要依赖 FGC,异步就能完成完成内存伸缩。
相关问题讨论
如何修改 OnlyOffice 配置连接本地部署的 OnlyOffice Docs 服务器?
如果内存比较紧张,比如在 docker 环境中,我们可以通过设置-XX:MaxHeapFreeRatio 和-XX:MinHeapFreeRatio,减少 jvm 预留的空间:
查看原帖讨论 · 15,161 次浏览
相关内容