Press "Enter" to skip to content

增加JVM参数,限制Java运行时的可用内存

背景

一次项目巡检发现某个项目的函数执行TP99的波动很大:

看这个图感觉很离谱,随即排查问题原因,看到JVM的监控如下:

发现程序一直在执行fullGC,我们知道fullGC的成本是非常大的,这肯定是导致应用卡顿的原因。

尝试解决

我去看了机器的监控,发现服务是部署在8G内存的容器里面的,实际占用内存只有7%都不到。

通过这里我们知道,实际机器的内存还是有很大的富余的,那肯定是哪里限制了jvm去使用更多的内存了。

找到我们应用的启动脚本,发现下面一行配置:

#==========================================================================================
# JVM Configuration
# -Xmx256m:设置JVM最大可用内存为256m,根据项目实际情况而定,建议最小和最大设置成一样。
# -Xms256m:设置JVM初始内存。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存
# -Xmn512m:设置年轻代大小为512m。整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。
#          持久代一般固定大小为64m,所以增大年轻代,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8
# -XX:MetaspaceSize=64m:存储class的内存大小,该值越大触发Metaspace GC的时机就越晚
# -XX:MaxMetaspaceSize=320m:限制Metaspace增长的上限,防止因为某些情况导致Metaspace无限的使用本地内存,影响到其他程序
# -XX:-OmitStackTraceInFastThrow:解决重复异常不打印堆栈信息问题
#==========================================================================================

JAVA_OPT="-server -Xms256m -Xmx256m -Xmn512m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m"

好吧,查到问题所在了,这里配置jvm的内存限制,限制的太小了,改成 `JAVA_OPT=”-server –Xms3550mXmx3550mXmn2g -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m”` 重新发布

各项指标都恢复正常了!

后续

可能有的同学要问了,这个jvm限制参数有啥用? 为啥要配置他?我可以不配置吗?

查阅相关资料发现,如果你不配置这个限制的话,他默认会使用系统可用内存的1/4来作为最大内存。

比如你系统内存32G,那么默认你不配置的话,你的应用只能用到8G。

如果是多应用共享,你是否真的可以使用8G ? 如果是独占服务器,剩下的24G内存是否浪费?

还有一种情况是容器环境,虚拟机可能128G内存,然而只给你容器分配了8G内存,如果这时候你不指定的话,JVM可能获取到的就是128G内存的1/4,显然他会导致你超额使用的情况。

所以,最好还是指定下你的应用JVM的内存配置在一个合理的值。

参考资料:

https://blog.csdn.net/wc1695040842/article/details/109160209

https://www.jianshu.com/p/de0c4118f2ce

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注