Java垃圾回收(GC)机制笔记
JVM虚拟机
一、 GC的基础知识
- 什么是垃圾?
C++ new delete
JAVA new ?
自动类型回收,编程上简单,系统不容易出错,手动释放内存,容易出现两种类型的问题:
(1) 忘记回收
(2) 多次回收 - 如何定位垃圾
(1) 引用计数(count)
(2) 根可达算法 - GC Algorithms(垃圾回收的算法)
(1) Make-Sweep(标记清除):位置不连续,产生碎片。
(2) Copying(拷贝):没有碎片,浪费内存。
(3) Make-Compact(标记压缩):没有碎片,效率低。 - JVM内存分代模型(用于分代垃圾回收算法)
(1)部分垃圾回收使用的模型。
(2)新生代+老年代+(永久代1.7)/元数据区(1.8)Metaspace
1、永久代 元数据-Class
2、永久代必须指定大小限制,元数据可以设置也可以不设置,无上限(受限物理内存)。
3、字符串常量 1.7-永久代,1.8-堆。
4、MethodArea逻辑概念,永久代,元数据。
(3)新生代 = eden+2个survivor区
1、YGC回收之后,大多数对象会被回收,活着的被copy进入s0区
2、再次YGC后,活着的对象eden + s0 ->s1
3、再次YGC后,eden+s1->s0
4、年龄足够->老年代
5、s区装不下->老年代
(4)老年代
1、顽固分子
2、老年代满了 FGC(FULL GC)
(5)GC Tuning(Generation) 内存调优
1、尽量减少FGC
2、MinorGC = YGC
3、MajorGC = FGC
5.常见的垃圾回收器
(1)Serial 年轻代 串行回收
(2)PS 年轻代 并行回收
(3)ParNew 年轻代 配合CMS回收
(4)SerialOld 老年代 串行回收
(5)ParallelOld 老年代 并行回收
(6)ConcurrentMarkSweep 老年代 并发的,垃圾回收和应用程序同时运行,降低STW时间(200ms)
(7)G1(10ms)
(8)ZGC(1ms)PK C++
(9)Shenandoah
(10)Epsilon
1、垃圾回收器的发展路线,是随着内存越来越大的过程而演进
2、从分代算法演变成不分代算法
Serial算法 几十兆
Parallel算法 几个G
CMS 几十个G,承上启下,开始并发回收
采用的算法:三色标记算法-错标-增量更新-Remark +写屏障
G1上百G内存,逻辑上分代,物理不分代
采用的算法:三色标记算法+SATB +写屏障
ZGC -Shenandoah-4T,逻辑物理都不分
采用的算法:ZGC ColoredPointers(颜色指针,着色指针)+读屏障。Shenandoah ColoredPointers(颜色指针,着色指针)+写屏障。
Epsilon 啥也不干(调试,确认不用GC参与就能干完活)
3、JDK诞生Serial,提高效率诞生了PS,为了配合CMS,诞生了ParNew(加强PS),CMS是1.4版本后期引入。CMS是里程碑式的GC,它开启了并发回收的过程,但是CMS的毛病较多,因此目前没有任何一个JDK版本的默认是CMS并发垃圾回收,是因为无法忍受STW。
4、JVM调优主要是这6个常见垃圾回收器组合:
注:调优主要是调吞吐量,或者调响应时间(STW时间)。
(1)Serial+ SerialOld
(2)ParallelScavenge +ParallelOld(JAVA1.8默认垃圾回收可以叫PS+ PO 又称ParallelGC)
(3)ParNew+CMS
5、物理分区,逻辑上分代的垃圾回收器G1
二、 调优前的基础概念:
1.吞吐量:用户代码执行时间/(用户代码执行时间+垃圾回收时间)
2.响应时间:STW时间越短,响应时间越好。
所谓调优,首先确定,追求啥,吞吐量优先,还是响应时间优先?还是在满足一定的响应时间的情况下,要求达到多大的吞吐量…
问题:
科学计算,吞吐量,数据挖掘,thrput。吞吐量优先的一般:(PS+PO)
响应时间:网站GUI API(1.8G)
什么是调优?
- 根据需求进行JVM规划和预调优
- 优化运行JVM运行环境(慢,卡顿)
- 解决JVM运行过程中出现的各种问题(OOM)
JVM调优第一步,了解JVM常用命令行参数
(1)JVM的命令行参数参考:
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
(2)JVM命令参数分类
标准:-开头,所有的hotSpot都支持(显示当前JDK默认的GC
java -XX:+PrintCommandLineFlags -version )
非标准:-X开头,特定版本hotSpot支持特定命令
不稳定:-xx开头,下个版本可能取消
java -version
java -x
java -XX:+PrintFlagsWithComments //只有debug版本能用