微服务架构-JVM参数调优-069:jvm垃圾收集算法与垃圾收集器

1 回收对象判断之引用计数法

课程内容:
1.为什么要有垃圾回收机制
2.jvm如何判断对象是否应该被回收
3.jvm垃圾回收算法
4.常用的垃圾收集器介绍
5.G1收集器介绍

jvm怎么判断一个对象是否要被回收?(对象是否为垃圾)
引用计数法(当前对象有没有被引用)
在这里插入图片描述
引用计数法:如果一个对象没有被任何引用指向,则可视之为垃圾。
缺点:不能检测到环的存在。

控制台打印gc日志

public class Demo1 {

    private Object next;

    public static void main(String[] args) {
        Demo1 a = new Demo1();
        Demo1 b = new Demo1();
        a.next = b;
        b.next = a;
        a = null;
        b = null;
        System.gc();
    }
}

Configuration设置
VM options:-verbose:gc -XX:+PrintGCDetails
控制台打印:

[GC (System.gc()[gc方式[) [PSYoungGen: 5263K[新生代执行前大小]->744K[新生代执行后大小](153088K[新生代总大小])] 5263K[堆执行前大小]->752K[堆执行后大小](502784K[堆总值]), 0.0008635 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]  [minor gc]
[Full GC (System.gc()) [PSYoungGen: 744K->0K(153088K)] [ParOldGen: 8K->592K(349696K)] 752K->592K(502784K), [Metaspace: 3115K->3115K(1056768K)], 0.0052559 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 153088K, used 3947K [0x0000000715f80000, 0x0000000720a00000, 0x00000007c0000000)
  eden space 131584K, 3% used [0x0000000715f80000,0x000000071635afd8,0x000000071e000000)
  from space 21504K, 0% used [0x000000071e000000,0x000000071e000000,0x000000071f500000)
  to   space 21504K, 0% used [0x000000071f500000,0x000000071f500000,0x0000000720a00000)
 ParOldGen       total 349696K, used 592K [0x00000005c1e00000, 0x00000005d7380000, 0x0000000715f80000)
  object space 349696K, 0% used [0x00000005c1e00000,0x00000005c1e94100,0x00000005d7380000)
 Metaspace       used 3127K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 338K, capacity 388K, committed 512K, reserved 1048576K

判断当前是否采用引用计数法

// 判断当前是否采用引用计数法
public class Demo2 {

    private Object next;

    private byte[] bytes;

    public Demo2() {
        bytes = new byte[1024 * 1024 * 20];
    }

    public static void main(String[] args) {
        Demo2 a = new com.mayikt.Demo2();
        Demo2 b = new com.mayikt.Demo2();
        a.next = b;
        b.next = a;
        a = null;
        b = null;
        System.gc();
    }
    // 执行gc以后如果大小大于40m,说明对象没有被回收,如果小于40m,说明对象被回收
}

运行结果:
在这里插入图片描述

2 回收对象判断之根搜索算法

根搜索算法:通过一系列名为”GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
在这里插入图片描述

3 垃圾回收算法之复制算法

为什么jvm不直接采用gcroot去回收整个堆?
效率不高,我们程序开发创建的对象99.99%的对象,基本存活不到3秒钟。

分代算法:根据对象的存活周期的不同将内存划分成几块,新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。新生代对象朝生夕死,对象数量多,只要重点扫描这个区域,那么就可以大大提高垃圾收集的效率。另外老年代对象存储久,无需经常扫描老年代,避免扫描导致的开销。
在这里插入图片描述
新创建的对象放在Eden区,Eden区创建满了根据gcroot算法回收对象,如果有对象依靠gcroot存活,把当前对象存入到S0区,年龄加1,其他所有对象被回收。

复制算法:将可用内存分为两块,from域和to域,每次只是使用from域,to域则空闲着。当from域内存不够了,开始执行GC操作,这个时候会把from域存活的对象拷贝到to域,然后直接把from域进行内存清理。
在这里插入图片描述
S0和S1对象不断复制,年龄不断增加,经过15次复制(年龄到达15)对象转入老年代。

4 垃圾回收算法之标记算法

标记清除算法
1.标记阶段:找到所有可访问的对象,做个标记;
2.清除阶段:遍历堆,把未被标记的对象回收
该算法一般应用于老年代,因为老年代的对象生命周期比较长。
缺点:内存碎片问题,内存浪费。
标记压缩算法
标记清除算法和标记压缩算法非常相同,解决内存碎片化。
注意是标记可达对象,空出一块区域将不可达的对象进行压缩,采用指针碰撞,然后直接删除压缩区域。
缺点:速度慢,整个过程都是stw(stop the world)整块区域长时间停止。

5 新生代回收器介绍

在这里插入图片描述
新生代垃圾回收器采取的垃圾回收算法都是复制算法。
Serial收集器
是一个单线程的垃圾回收器,使用新生代复制算法。
在桌面应用比较多(单线程服务器上,堆内存比较小的应用使用效率比较高)
在这里插入图片描述
当gc执行时候会暂停所有的线程,这个步骤简称STW (Stop The World)

Parnew收集器
在清理时候parnew 采用多线程收集,也是在新生代复制算法,STW。
在这里插入图片描述
Parallel Scavenge收集器(简称PS)
多线程收集,也是采用复制算法
达到到可以控制的吞吐量:用户执行时间/(用户执行时间+gc暂停时间)
-XX:MaxGCPauseMillis 垃圾回收器最大停顿时间
-XX:GCTimeRatio 吞吐量大小 (0,100) 默认最大99

minor gc,新生代回收的gc(复制算法)
major gc,老年代回收的gc(标记清除、标记压缩算法)
full gc,清理整个堆空间—包括新生代和老年代。

6 CMS回收器介绍

CMS 收集器 采用标记清除算法 用户线程和gc在一段时间进行并行

  1. 初始标记:标记老年代中直接与gcroot关联的对象 (STW)
  2. 并发标记:用户线程会和gc一起执行 上面标记的gcroot对象下关联的对象(非直接)
  3. 重新标记:扫描新生代和老年代新出现的对象 STW
  4. 并发清除:清除未标记对象,用户线程会和gc一起执行
    在这里插入图片描述

优点:并发收集、低停顿
缺点:占用大量的cpu资源、无法处理浮动垃圾、会产生碎片化
cms不会在老年代占满的时候去回收,默认在92%的时候开始cms回收;
支持在重新标记之前开启一次minor gc;
默认情况下如果执行一次full gc,cms采用标记整理算法回收碎片。

7 G1回收器介绍

G1收集器:没有很明确的分代,把堆区间分为很多个区域。
在这里插入图片描述
Region之H区域
H区隶属于老年代,存储大对象(大于0.5个Region),对于H区也无法容纳的对象,G1会寻找一个连续的HRegion来存放该对象,如果找不到会启动full gc回收。
YGC
清理S0区域,然后生成一个新的S1区,其他的区域就会变成空白的。
在这里插入图片描述
Cset
代表本次gc要回收region的集合
Rset(Remembered set)
在这里插入图片描述
Region的一块区域,记录其他region引入当前region的对象。在GC的时候,对于old->young和old->old的跨代对象引用,只要扫描对应的CSet中的RSet即可。
Mix GC
在这里插入图片描述

  1. 初始标记:gcroot标记region
  2. 并发标记:与之前gcroot标记过的region有rset关系;
  3. 最终标记:参考cms重新标记;
  4. 筛选回收:有一张表记录各region回收的百分比,清理垃圾较多的region,H区也会一起回收。

G1收集器优点:分成很多块相对需要回收的区域很小,需要扫描的区域很少,所以G1收集器相对cms收集器效率更高。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值