导图社区 JVM性能优化总结
下图是JVM性能优化总结的思维导图,主要的问题有内存问题、CPU问题、线程问题,主要知识点从垃圾收集器和GC性能衡量指标做介绍,还为我们介绍了如何更好的使用JVM。
社区模板帮助中心,点此进入>>
论语孔子简单思维导图
《傅雷家书》思维导图
《童年》读书笔记
《茶馆》思维导图
《朝花夕拾》篇目思维导图
《昆虫记》思维导图
《安徒生童话》思维导图
《鲁滨逊漂流记》读书笔记
《这样读书就够了》读书笔记
妈妈必读:一张0-1岁孩子认知发展的精确时间表
JVM性能优化
问题
内存问题
内存溢出
堆内存溢出(OutOfMemoryError)
程序问题,例如不设限的缓存队列或环形队列,在log4j日志中遇到过
栈内存溢出(StackOverflowError)
程序BUG,例如不合理的递归
元空间溢出(OutOfMemoryError)
规则脚本、Spring、Mybatis、Groovy等需要用动态创建类的常见容易发送元空间溢出问题
-XX:TraceClassUnloading
字符串常量池过大
不合理是String.intern()的使用
堆外内存溢出
需要大量频繁IO操作的中间件都用到了堆外内存,例如Netty
垃圾收集异常
YGC频次高
FGC频次高
单次GC的STW时间长
GC调优的思路就是围绕这三个问题展开
CPU问题
热点方法
热点栈
线程问题
线程泄漏
线程死锁
知识点
JVM内存模型
堆(heap):JVM中最大的一块内存空间,被所有线程共享,几乎所有对象和数组都被分配到了堆内存中。
程序计数器(Program Counter Register):用于记录各个线程执行的字节码的地址
方法区(Method Area):主要用来存放已被虚拟机加载的类的相关信息,包括类信息、静态变量、常量、即时编译后的代码等等
永久代是HotSpot的方法区实现,Java 8已经用元空间替代了永久代
(1)方便与JRockit VM融合 (2)永久代内存垃圾回收的效果不好
静态变量、运行时常量池、字符串常量池都移动到堆中,方便GC调优
元空间中只存储类相关的信息
虚拟机栈(VM Stack):线程私有的内存空间,用于管理Java函数的调用
本地方法栈(Native Method Stack):用于管理本地方法的调用
垃圾收集器
如何判断一个对象可被回收?
引用计数法
可达性分析法
当一个对象到GC Roots没有任何引用链相连,就表示该对象可回收
Java中的GC Roots
虚拟机栈(本地变量表)中应用的对象
方法区中静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI引用的对象
Java中的引用
强引用(Strong Reference):被强引用关联的对象永远不会被垃圾收集器收集
软引用(Soft Reference):软引用关联的对象,只有当系统要发生内存溢出时,才会去回收软引用关联的对象
弱引用(Weak Reference):弱引用关联的对象,只能生存到下一次垃圾收集发生之前。
虚引用(Virtual Reference):虚引用关联的对象,在它被收集器回收的时候可以收到一个系统通知
垃圾收集算法
标记-清除算法
优点:不需要移动对象,简单
缺点:效率低,GC产生内存碎片
复制算法
优点:简单高效,不会产生内存碎片
缺点:内存使用率低,可能产生频繁复制问题
标记-整理算法
优点:结合了前面两种算法
缺点:仍然需要移动局部对象,效率不够高
分代收集算法
对象的生存时间,大部分都是朝生夕死,少量的会存活很长时间
优点:分代回收,不同的区域采用不同的算法,年轻代复制整理,老年代标记清理或标记整理
缺点:对于长时间存活的对象效果不明显
Serial
ParNew
Parallel Scavenge
年轻代
CMS
初始标记
并发标记
重写标记
并发清除
Serial Old
Parallel Old
老年代
G1
G1的特点
物理上分割成不同的区块(Region)
逻辑上依然是分为新生代、老年代
可以设定一个可预期的停顿时间(软限制),然后系统会有一个算法尽量满足
比较适合大内存管理(8G以上)
按照全部堆内存占用的比例触发Mixed GC,跟CMS不一样,CMS是按照老年代的使用比例触发Full GC
G1的执行过程
最终标记
筛选回收
G1的运行过程
Minor GC:只回收年轻代的Region
Minor GC + 并发标记
Mixed GC:既回收年轻代的Region,也回收老年代的Region
ZGC
GC性能衡量指标
吞吐量:应用程序花在GC上的时间除以总的运行时间
停顿时间:垃圾收集运行过程中,应用程序暂停服务的时间(所有STW阶段的和)
垃圾回收频率:多久发生一次YGC或FGC
如何更好地使用
事前
JVM参数优化
JVM内存空间合理分配
打印GC日志详情
避免NPE堆栈被压制
关闭偏向锁
发生OOM的时候保留堆dump现场
代码review
是否有不合理的数据结构使用
使用的中间件对内存的使用是否有特殊要求
事中
监控配置
预警规则配置
事后
MAT,分析heapdump文件
arthas,找到热点栈
arthas,找到耗时最长的方法栈
分析GC日志
safepoint频次
GC过程中耗时长的阶段,发现造成stw的元凶
gceasy:用于分析gc日志