2核2G的机器,除了FULL GC 其他时候cpu使用率不到10%,buckUp服务器,主服务器异常的时候偶尔顶一下,也用于灰度发布
full GC SWT超过2秒,大概率会导致当机,阿里云便宜服务不建议开swap,只要用到swap就会当机
GC调优
- jcmd
- jcmd [pid] VM.flags 查看当前已经设置的vm参数
- jcmd 还有很多很多命令
- 经研究添加参数如下
-Xlog:gc*:gc.log:time:filesize=100m:filecount=2
-XX:ConcGCThreads=2 -XX:G1HeapWastePercent=2 -XX:MaxGCPauseMillis=30 -XX:InitiatingHeapOccupancyPercent=30
-XX:G1PeriodicGCInterval=500 -XX:MinHeapFreeRatio=12 -XX:MaxHeapFreeRatio=40
-XX:MaxDirectMemorySize=96m -Xms448m -Xmx800m -XX:G1HeapRegionSize=2m -XX:MetaspaceSize=144m -XX:MaxMetaspaceSize=192m
- 日志相关
- Xlog:gc*:gc.log:time:filesize=100m:filecount=2
- 表示打印gc* 表示GC详细日志,gc.log是输出的文件,filesize是文件最大大小,filecount是最多保留文件数,gc.log.0,gc.log.1
- 回收效率相关
- ConcGCThreads 标记线程,默认2核只有1个,这里改为2
- InitiatingHeapOccupancyPercent 新老混合回收时机,老年代占堆大小的比例,默认45%
- G1HeapWastePercent 混合回收整理出来的空闲空间占heap的5%时(默认值),终止本次回收,改为2
- G1ReservePercent 预留缓冲区百分比默认10%,如果业务没有比较突发的内容占用,可以设置小一点
- XX:+ParallelRefProcEnabled 开启软应用并发回收,在springboot/Mybatis有大量缓存用到了软应用
- MaxGCPauseMillis 最大停顿时间,默认200,这里改为30
- 从GC日志上看,效果是当有一次GC时间大于100ms的值后,后面的GC就比前面更频繁
- 同时还有一个等效参数 -XX:GCTimeRatio=n,表示最大可以使用1/n 的时间来用于GC,没有MaxGCPauseMillis好理解
- 定期垃圾收集
- G1PeriodicGCInterval 500ms内如果没有触发垃圾回收就做一次定期回收
- G1PeriodicGCSystemLoadThreshold 定期回收时系统负载最小比例,超过这个比例不进行定期回收
- MinHeapFreeRatio/MaxHeapFreeRatio 空闲内存最小/最大 百分比,默认值 40/70,设置小可以更快的归还内存给系统
- 内存大小相关
- MaxDirectMemorySize:最大直接内存
- Xms 初始堆大小
- Xmx 最大堆大小
- G1HeapRegionSize 堆分区大小内存低于2G为1m,改为2m,减少巨型对象机率
- MetaspaceSize 初始元空间大小
- 144m为加载类总数:21724时占用值,主要避免启动时频繁FULL GC
- MaxMetaspaceSize 元空间最大值
- 不建议低于192m
- 核心点: ConcGCThreads,MaxGCPauseMillis 配合 Xms和Xms,其他参数仅供参考
netty直接内存优化
-Dio.netty.tryReflectionSetAccessible=true --add-opens=java.base/jdk.internal.misc=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED
- 开启直接低层内存分配,open netty需要反射的类
- 参考: https://www.xinfinite.net/t/topic/10251
阿里云服务器关闭crashkernel(更新)
- 我这台2c2G的ubuntu22.04服务器是开着crashkernel的,每次机器当机时,我好像也没用到这个关了他
free -m #查询当前机器内存,明显低于2G
# total used free shared buff/cache available
#Mem: 1673 1164 86 2 421 346
cat /sys/kernel/kexec_crash_size
#我这台显示:201326592 占用有192m
sudo nano /etc/default/grub
# 将crashkernel=0M-1G:0M,1G-4G:192M,4G-128G:384M,128G-:512M 改为crashkernel=0M
sudo apt remove kexec-tools #卸载内核dump工具包
sudo systemctl disable --now kdump-tools #关闭内核转储服务
sudo systemctl mask kdump-tools #禁用内核转储服务
grub-mkconfig -o /boot/grub/grub.cfg #生成新的启动文件
reboot #有点虚,怕起不起来
- 效果 1865-1673正好192m
free -m
# total used free shared buff/cache available
#Mem: 1865 188 1267 2 408 1522
- 顺便调大了一点Xms480,降低GC的CPU点用
- 参考: https://linux.do/t/topic/461292
- 注意,不要开swap,不要开swap,不要开swap!
一些有用的参考
很多网上搜到的参考是没用的
- G1调优实践日记 https://blog.csdn.net/lovejj1994/article/details/109620239
- G1相关参数配置 https://www.cnblogs.com/yu007/p/17900844.html
- Java12 G1GC返回未用堆内存给操作系统 https://www.cnblogs.com/androidsuperman/p/11743103.html
- java 通过shell脚本设置jvm参数 https://blog.51cto.com/u_16175472/8593285
- 参数多的时候,很有用,一行根本编辑不下
- 注意bash变量等号两边不能有空格