JVM调优
1、什么是调优
- 根据需求进行进行jvm规划预调优
- 优化运行jvm运行环境(慢,卡顿)
- 解决jvm运行过程中出现的各种问题(OOM)
OOM内存溢出 观测有哪些对象产生了OO
2、jvm3种参数
-
-* 标准参数
-
-X*非标参数
-
-XX*有700多个 没有直接显示出来显示命令 java -XX:+PrintFlagsFinal | more 计数 java -XX:+PrintFlagsFinal | wc -l
查看当前jvm使用的GC
java -XX:+PrintCommandLineFlags -version
3、GC常用参数
-
jvm常用参数
- -Xmn -Xms -Xss 年轻代 最小堆 最大堆 栈空间
- -XX:+UseTLAB 使用TLAB,默认打开
- -XX:+PrintTLAB 打印TLAB的使用情况
- -XX:TLABSize 设置TLAB的大小
- -XX:+DisableExplictGC System.gc() 不管用FGC
- -XX:+PrintGC
- -XX:+PrintGCDetails
- -XX:+PringHeapAtGC
- -XX:+PrintGCTimeStamps
- -XX:+PrintGCApplicationConcurrentTime(低) 打印应用程序时间
- -XX:+PrintGCApplicationStoppedTime(低) 打印暂停时长
- -XX:+PrintReferenceGC (重要性低)记录回收了多少种不同引用类型的引用
- -verbose:class 类加载详细过程
- -XX:+PrintVmOptions
- -XX:+PrintFlagsInitial -XX:+PrintFlagsFinal 必须会用的
- -Xloggc:opt/log/gc.log
- -XX:MaxTenuringThreshold 升代年龄 最大15
- 锁自旋次数(不建议) -XX:+PreBlockSpin
- 热代码检测参数(不建议) -XX:CompileThreshold
- 逃逸分析(不建议)
- 标量替换(不建议)
- . . .
-
Parallel常用参数
- -XX:SurvivorRatio
- -XX:PreTenureSizeThreshold 设置大对象大小
- -XX:MaxTenuringThreshold (对象被复制的次数)
- -XX:+ParallelGCThread 并行回收器的线程数,同样适用于CMS,一般设为和CPU核数相同
- -XX:+UseAdaptiveSizePolicy 自动选择各区大小比例
-
CMS常用参数
- -XX:+UseConcMarkSweepGc
- -XX:ParallelCMSThreads CMS线程数量
- -XX:CMSInitiatingOccupancyFraction 使用多少比例老年带开始CMS收集 默认是68%(近似值),如果频繁发生SerialOld卡顿应该调小(频繁CMS回收)
- -XX:+UseCMSCompactAtFullCollection 在FGC时进行压缩
- -XX:CMSClassUnloadingEnable
- -XX:CMSInitiatingPermOccupancyFraction 达到什么比例后对perm进行回收
- GCTimeRatio 设置GC时间占用程序运行时长的百分比
- -XX:MaxGCPauseMillis 停顿时间,是一个建议时间,GC会尝试用各种手段达到这个时间,比如减小年轻代
-
G1常用参数
- -XX:+UseG1GC
- -XX:MaxGCPauseMillis 建议值,G1会尝试调整Young区的来达到这个值
- -XX:+G1HeapRegionSize ? GC的间隔时间
- -XX:+G1HeapRegionSize 分区大小,建议逐渐增大该值,1 2 4 8 16 32 随着size增加 垃圾存活时间更长,GC间隔更长,但每次GC的时间也会更长 ZGC做了改进(动态区块大小)
- G1NewSizePercent 初生代最小比例,默认为5%
- G1MaxNewSizepercent 新生代最大比例,默认为60%
- GCTimeRatio GC时间建议比例,G1会根据这个值调整对堆空间
- ConcGCThreads 线程数量
- InitiatingHeapOccupancyPercent 启动G1的堆空间占用比例
3、jvm诊断工具
阿里的arthas (阿尔萨斯)
-
常用命令
-
dashboard 可以看见运行起来线程的情况
-
jvm 会打印当前虚拟机信息包括GC处理器的类型
-
trace ABC a 链路追踪命令
-
heapdump 替代jmap命令把当前堆内存信息导入到文件中
-
thread 打印当前进程所有线程信息
-
thread -b 查找死锁
-
jvm 与jinfo类似 打印当前jvm的信息
-
jad class名 反编译命令
-
redefine 在线修改class
-
4、jvm常用命令
-
jmap - histo PID | head -20 查找有多少对象一直未被回收占的内存多,但是jmp会是堆内存暂停,堆内存越大暂停时间越长
jmap -dump:format=b,file=2022031801.hprof PID 进行堆内存的转储:把堆内存导出转成文件,把这个文件拿出来分析,不建议用,用下一个
设置JAVA启动参数:-XX:+HeapDumpOnOutOfMemoryError 设置在发生OOM时把堆内存导出生成文件 大公司堆内存超级大10G的堆内存如果用工具的话24小时内分析不出结果
-
jps 会列出系统中java的进程
-
jinfo PID 会把PID进程相关的属性都列出来
-
jstat -gc PID 500 跟踪当前线程GC的一些信息
-
jstack PID 会打印出当前进程中的所有线程信息(线程名,编号,优先级,线程ID,状态…) 包括显示调用栈.作用查死锁.
5、linux CPU占用过高
- top 显示运行在当前系统的所有进程,并显示占用资源信息
- top -Hp PID 会列出当前进程中的所有线程占用的资源信息
- jstack PID > 文件名.log 导出线程栈信息
- 找到占用CPU最大的线程ID 转成16进制 在log文件中搜索,得到线程信息
6、生产环境调优手段
- 在压测环境下进行jvisualvm 远程连接进行观察
- 生产环境上做了负载均衡,从负载均衡的服务器群组上,摘下来一台进行jmap 文件的导出然后用jvisualvm观察
- 用tcpcp 复制http请求到测试环境进行jvisualvm进行观察