咕泡课程部分笔记
基于JDK1.8
JVM架构
JDK自带命令
jps:查看当前java进程
jinfo:查看或修改JVM参数
jstat:查看class/gc状态信息
jstack:查看线程信息,查看死锁
jmap:生成堆内存的快照
jps
jinfo -flag UseG1GC PID
jinfo -flag name=value PID [条件] {manageable} 实时修改某个进程中JVM参数值,manageable才能修改
jstat -class PID 1000 10 查看类的信息,每秒打印1次,共打印10次
jstat -gc PID 1000 10 查看gc的信息,每秒打印1次,共打印10次
jstack PID
jmap -heap PID 发生OOM时,能把堆内存信息导出来分析是什么对象占用内存空间比较大
jmap -dump:format=b,file=heap.hprof PID dump出文件 发生OOM自动dump设置JVM参数:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof
自带工具
- jconsole
- jvisualvm
-安装插件
-连接本地和远端 - jmc
- arthas
调优的几个维度
(1)堆的使用
如果OOM,排查哪个对象占用内存比较大
自带命令/工具不够强大,其他工具:
- MAT(MemoryAnalyzer):打开堆内存文件dump.hprof,进行分析
- perfMa:在线分析dump.hprof
(2)垃圾回收 GC日志
打印出GC日志,配置参数:
//当前目录下生成gc.log日志
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:gc.log
- 分析gc.log文件:
使用parallelGC,youngGen回收前65536k回收后7986k,metaspace也会进行垃圾回收(回收率很小) - 分析GC日志工具:
gcviewer.jar:运行java -jar gcviewer.jar
GC调优维度:吞吐量、停顿时间
在线工具:GCeasy
然后不断选择垃圾收集器,观测吞吐量和停顿时间的最佳值
JVM调优思路:
- cpu飙升
- 内存空间不够用了
- gc次数太多–>用户线程代码执行受影响–>cpu使用会高
- 尽可能提高吞吐量 减少停顿时间
吞吐量 最小停顿时间 最大停顿时间 平均停顿时间
默认设置
调整堆的大小
设置停顿时间
-XX:+UseG1GC -XX:MaxGCPauseMillis=15
总结:停顿时间不要太严格,否则GC次数会增加,怎么能找到最优值,只能不断的测试
启动并发GC时(堆内存的占比)
查看堆使用比例:
jinfo -flag InitiatingHeapOccupancyPercent PID
-XX:InitiatingHeapOccupancyPercent =45 默认占45%,也就是整个堆的45%的使用率
设置JVM参数-XX:InitiatingHeapOccupancyPercent =50
G1建议:
- G1GC不要手动设置young区大小
- 可以设置停顿时间,但不要太严格
- 对其他参数进行调整
-XX:InitiatingHeapOccupancyPercent
-XX:G1HeapWastePercent 堆浪费比例
-XX:G1MixedGCLiveThresholdPercent mixGC时存活比例
ConcGcThreads=n 增加垃圾回收标记线程数量
深入G1
G1和CMS的区别:
CMS:标记-清楚 空间碎片
G1:标记-整理
(1)Region 收集方式 Garbage First 优先会收集垃圾比较多的区域
(2)G1 RememberedSet RSet
(3)多核cpu、大内存至少6G
(4)停顿时间
(5)CSet:一组被回收的分区的集合存活对象移动到另外分区CSet<1%
高并发场景下调优
JVM调优相关问题
- GC的次数频繁,怎么办
- cpu持续飙升
- OOM
- 内存泄露和内存溢出的区别?
内存慢慢地泄露,最终导致内存溢出 - 方法区中的回收主要是什么内容
没有用的类的信息,常量 - 不可达的对象一定会被回收吗?
- Young GC会stop the world吗?
新生代的GC收集器 -->暂停用户线程代码