JVM性能优化(二)--垃圾回收
一、垃圾回收
在java中,不需要手动的去释放一个对象的内存的,而是由虚拟机自动执行。在JVM中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足时,才会触发执行,扫面那些没有被任何引用的对象,并将它们添加到要回收的集合中,进行回收。
二、 如何确定对象为垃圾
1、引用计数法
当一个对象没有任何指向其的引用,则该对象为垃圾。
弊端:互相引用的对象,永远不能判定为垃圾。
2、可达性分析
使用GC Root对对象进行向下寻找,看对象是否可达。
可以作为GC Root:
类加载器、Thread、虚拟机栈中的本地变量表、static成员等。
三、对象清除算法
- 标记-清除
- 标记-整理
- 标记-复制
四、垃圾收集器
Serial收集器
- 单线程
- 标记-复制算法
- 新生代
- 暂停应用程序线程
ParNew收集器
- Serial收集器的多线程版本
- 标记-复制算法
- 新生代
- 暂停应用程序线程
Parallel Scavenge收集器
- 多线程并行
- 标记-复制
- 新生代
- 类似ParNew收集器
- 更关注系统的吞吐量
Serial Old 收集器
- 类似Serial收集器
- 单线程
- 标记-整理
- 老年代
Parallel Old收集器
- 多线程并行
- 标记-标记整理
- 老年代
- 吞吐量优先
CMS收集器
- 并发收集器,四个阶段
- 标记-清除算法
- 老年代
- 更加关注减少垃圾收集时间
G1收集器
- 并行并发
- 标记-整理 不存在空间碎片
- 将堆内存空间划分为独立的Region
- 优先清理垃圾多的区域
- 可以自定义 GC 停顿时间 -XX:MaxGCPauseMillis=200
- JDK7开始使用、JDK8成熟、JDK9默认新老收集器
五、垃圾收集器分类及适用场景
- 串行 内存较小的设备
- 并行 后台处理,高吞吐量
- 并行 web场景,停顿时间短
六、吞吐量、停顿时间
性能调优关注的指标
- 吞吐量=执行用户代码时间/执行用户代码时间+垃圾收集时间
- 停顿时间=垃圾收集器执行垃圾回收的时间
七、垃圾收集器选择
- 优先调整堆内存大小,默认垃圾收集器
- 内存小于100M ,单线程收集器
- 允许停顿时间超过1S,并行收集器或默认
- 要求停顿时间小于1S,并发收集器
- G1: 存活对象占堆的50%以上,垃圾回收时间长
八、常用命令&常用工具
命令
- jinfo 查看调整JVM参数信息
- jstat 查看类装载信息
- jstack 查看线程堆栈信息,排查死锁线程
- jmap 查看堆内存信息,dump堆内存 堆内存溢出,自动生成dump文件命令:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof
工具
- jconsole
- jvisualvm
- MAP 分析堆内存dump文件用
- GC日志 https://gceasy.io
九、性能优化
十、常用调优参数
-
设定堆内存大小
-Xmx:堆内存最大限制。 -
设定新生大小。 新生代不宜太小,否则会有大量对象涌入老年代
-XX:NewSize:新生代大小
-XX:NewRatio 新生代和老生代占比
-XX:SurvivorRatio:伊甸园空间和幸存者空间的占比 -
设定垃圾回收器 年轻代用 -XX:+UseParNewGC 年老代用-XX:+UseConcMarkSweepGC
-
打印
-XX:+PrintGC:输出形式:[GC 118250K->113543K(130112K), 0.0094143 secs] [Full GC 121376K->10414K(130112K), 0.0650971 secs]
-XX:+PrintGCDetails:输出形式:[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs] [GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs]
-XX:+PrintGCTimeStamps -XX:+PrintGC:PrintGCTimeStamps可与上面两个混合使用,输出形式:11.851: [GC 98328K->93620K(130112K), 0.0082960 secs]
-XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中断的执行时间。可与上面混合使用。输出形式:Application time: 0.5291524 seconds
-XX:+PrintGCApplicationStoppedTime:打印垃圾回收期间程序暂停的时间。可与上面混合使用。输出形式:Total time for which application threads were stopped: 0.0468229 seconds
-XX:PrintHeapAtGC: 打印GC前后的详细堆栈信息
-Xloggc:filename:与上面几个配合使用,把相关日志信息记录到文件以便分析
-verbose:class 监视加载的类的情况
-verbose:gc 在虚拟机发生内存回收时在输出设备显示信息
-verbose:jni 输出native方法调用的相关情况,一般用于诊断jni调用错误信息