由于默认的jvm参数不够合理,一般使用前都建议按需调整,这里尝试抛砖引玉,给出我个人工作中总结的经验,欢迎大家一起讨论
服务类型
- http应用
- dubbo应用
java版本
使用java8支持容器化的版本:Java 8 Update 261 (8u261)
单个服务实现的资源标准
高配版
Cpu:4
Memory:8196M
低配版
Cpu:2
Memory:4096M
注意:内存最低不能低于1500,原因参考下面的堆外内存计算
启动参数
通用启动参数,高低配均相同
// 堆大小,menLimit来源于部署参数
-Xms${menLimit}m -Xmx${menLimit}m
// 存活与eden比例(默认)
-XX:SurvivorRatio=8
// 关闭偏向锁
-XX:-UseBiasedLocking
// 整型缓存
-XX:AutoBoxCacheMax=20000
// 与-Xmx == -Xms配合使用,在启动时提交所有内存
-XX:+AlwaysPreTouch
// 优化
-XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+ExplicitGCInvokesConcurrent
// OOM dump(需使用持久卷路径)
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/durability/log/$(date "+%Y-%m-%d_%H:%M:%S").hprof
// gc log(需设置日志收集)
-XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:/data/java/log/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1M
-Djava.awt.headless=true -Djava.net.preferIPv4Stack=true
-Duser.timezone=Asia/Shanghai -Dfile.encoding=UTF-8
关于为何关闭偏向锁可以参考:从源码看世界:偏向锁从入门到放弃_usebiasedlocking-CSDN博客
高配版
gc回收器使用g1
// 元空间
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m
// 栈大小
-Xss512k
// G1回收器
-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:G1HeapRegionSize=2M
低配版
gc回收器使用cms
// 元空间
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m
// 栈大小
-Xss256k
// CMS回收器
-XX:+CMSScavengeBeforeRemark
-XX:+UseConcMarkSweepGC
-XX:+CMSParallelRemarkEnabled
-XX:+UseCMSCompactAtFullCollection
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=80
-XX:+ParallelRefProcEnabled
-XX:+ExplicitGCInvokesConcurrent
// 增加新生代大小,减少YGC
-XX:NewRatio=1
-XX:MaxTenuringThreshold=5
内存计算
内存分为堆内/堆外,堆内固定大小,而堆外跟线程数、元空间、直接内存有关,因此通过计算堆外内存后反推到堆内大小
堆外内存
假设dubbo/tomcat线程数最大为1000,其它异步线程大概在500,即:
- 线程栈最大内存:
高配版:(1000 + 500) * 512K = 750M
低配版:(1000 + 500) * 256K = 375M
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m(low)/512m(high) ,即:
- 元空间最大内存:256M(low)、512M(high)
- 其它使用到的直接内存约为:128M
因此总量为
- 高配版:750 + 512 + 128 = 1390M
- 低配版:375 + 256 + 128 = 759M
堆内内存
假设容器内存剩余小于5%报警,预留3%作为缓冲容量
堆内存大小: 容器内存 * 92% - 堆外内存
docker镜像建议添加的功能
show-busy-java-threads
列出当前 java 进程 cpu 最高 top n 线程,使用方式
参考: github
arthas
Alibaba Java诊断利器
在控制台直接执行 arthas 命令即可
参考: github