美文网首页
内存回收(GC)

内存回收(GC)

作者: 双囍_小赵 | 来源:发表于2021-10-20 14:25 被阅读0次

首先我们要先明白什么是垃圾?就是没有任何指针指向的对象,可以成为可回收垃圾;

其次为什么需要垃圾回收?因为内存持续增长就像是生活垃圾持续产生得不到消耗,这样会造成程序问题,此时垃圾回收机制就要对程序内存进行不定时的管理和回收,以保证程序持续运行;

垃圾回收有两个步骤:

1. 垃圾确认算法

就是标记阶段,以方便接下来的清除;

标记具体有两种算法:引用计数算法、GCRoot可达性分析算法;

🧃引用计数算法:

对于每个对象都给他一个变量,当在使用一次这个对象就随之将这个变量+1,反之-1;当这个变量为0的时候表示这个对象不再被引用,可进行回收;

优点:计算简单方便,判断效率高;

缺点:需要单独的字段去计算,消耗内存空间,每次加减操作,消耗时间,最大问题是对于循环引用它就无法处理;

🥦可达性分析算法:

涉及到一个概念“GCRoot”,所有的GCRoot都存放在一个set列表中进行管理,那么什么东西可以作为GCRoot呢?

总结一句话就是:一个指针保存了堆区的对象,但是他自身不在堆区

例如:方法区静态常量、栈区的对象引用、本地方法栈的JNI引用...

优点:可以保证将每个内存垃圾进行回收;

缺点:需要遍历所有的root链,耗时;

2. 清除垃圾算法

这一步骤才是正式清理垃圾;

清除垃圾有多种算法:标记清除算法、复制算法、压缩算法....;

所有的清除必须基于快照;快照指的是定于某个时间将所有的内存数据复制一份,这就是快照;因为不可能全量复制堆区,堆区就这么大,不可能全量复制,在进行GC的时候数据不能变动了,所以此时就要Stop the world  STW,暂停用户程序。

🙂标记清除算法:

标记清除算法是最常见和使用的一种,他的标记使用的是可达性分析算法的方式,从引用根节点上开始标记所有被引用的对象;

清除:在堆内存从头到尾进行线性遍历,判断某对象的header中没有标记成可达性对象,则将其回收。

缺点:效率不高;容易产生大量的内存碎片;在进行GC时需要将用户的应用程序停掉,用户体验差。


🙃复制清除算法:

会开辟两块内存,将存活的对象复制到另外一块内存中,再将原本的全部清除,之后将指向地址转到新的内存中的对象中;

缺点:需要两倍空间;需要维护对象引用关系,时间开销大;适用于垃圾对象较少的情况,量级不大。

这就是S区域出现的原因,官方eden-S1-S2比例:8:1:1

😌标记压缩/整理算法:

bu同于复制清除算法,它是在同一块内存中进行整理,先进行清除,后进行整理排序;

等同于标记清除算法后在进行一次内存碎片整理;

标记存活的对象被整理后,会按照内存地址依次排列,而未被标记的会被清除,如此一来我们需要给新的对象分配内存时,JVM只需要持有一个起始地址即可,减少了维护一个新的内存列表的开销。

这三个清除算法对比:

            1. 复制算法最快,但是浪费内存;

            2. 标记压缩、整理算法相对平滑,但是和标记清除算法相比多一个整理,和复制算法相比多一个标记阶段,效率不够好;

😃分代收集算法:

这三个没有一个较优的:所以出现分代收集算法;分为年轻代和老年代、S区域;

70%~99%是生命周期短,存活率低,产生应用频繁的对象;

1%~30%是生命周期长的对象,存活率高,回收不如年轻代频繁;

年轻代使用复制算法回收对象较快;

老年代使用的是标记整理算法:标记-清理-整理;所以GC在老年代的处理的时间是年轻代的10倍时间;

😃增量收集算法:

在垃圾回收的过程中,应用程序处于STW状态,暂停了应用程序所有的线程,导致回收整个过程都很长,影响用户体验;

增量收集是保证回收内存一部分一部分进行回收,在此期间不间断的切换垃圾回收线程和应用程序线程执行,直到垃圾回收完成;

允许垃圾收集以分阶段的形式进行,标记,清理,整理;

增量最具代表性的是——CMS:JDK1.5之后第一个真正意义上的并发处理垃圾回收器;低延时->用户线程停顿短暂;

第一步:标记GCRoot对象(STW时间短);

第二步:标记GCRoot整个引用链,消耗大,这一步开启并发,用户线程不停止,但是数据会有变动;

第三步:重新标记有变动的数据,会出现STW;

第四步:并发清理,不停用户线程;

第五步:整理是不定时的;

CMS标记流程

三色标记法——降低延迟:

第一步初始标记:拿GC标记成灰色,如果没有引用标记成白色;

第二步并发标记——可达性分析:遍历完标黑色;

第三步重新标记——三色标记法:除了黑灰色状态,无状态对象再次标记;

第四步并发清理:清除白色;

😃分区算法

堆内存越大,GC耗时越长,分区为了一次GC的时间缩短,更好的控制回收的停顿时间 ,每次合理的回收若干小区间。

内存回收通常使用的是复合算法,不是某一种算法。

相关文章

  • android 内存泄漏(多文章摘录)

    内存泄漏 gc没有办法回收activity的内存。 垃圾回收(GC) 垃圾回收或GC(Garbage Collec...

  • 安卓中 GC

    [序言] GC是Java对内存回收机制,了解GC,应该从了解GC的概念、内存分配、识别哪些内存需要回收和回收方式几...

  • 直击面试,聊聊 GC 机制

    GC 中文直译垃圾回收,是一种回收内存空间避免内存泄漏的机制。当 JVM 内存紧张,通过执行 GC 有效回收内存,...

  • java内存分区及垃圾回收

    Android垃圾回收:分配内存-GC不回收软引用(GC_FOR_MALLOC)-增长到最大堆-(GC回收软引用(...

  • Java GC

    概述 GC => 垃圾回收 = 回收可用空间 + 压缩内存 内存管理 手动内存管理 => C | C++ 自动内存...

  • JVM 内存结构 和内存回收算法

    一、JVM 内存模型、GC 1.1GC是啥? GC是垃圾回收机制,java中将内存管理交给垃圾回收机制,这是因为在...

  • 垃圾收集器和内存分配策略

    GC需完成的三件事: 那些内存需要回收 什么时候回收 如何回收 为什么要了解GC和内存分配? 当需要排查内存泄漏和...

  • 2016.5.6

    1.引用问题强引用,不会被GC回收;软引用,在内存不足的时候会被GC回收;弱引用,无论内存是否足够,只要被GC扫描...

  • Java基础 (14) 垃圾回收

    1)GC算法(各种算法的优缺点以及应用场景)2)内存对象的循环引用及避免3)内存回收机制、GC回收策略、GC原理时...

  • java(内存和gc)

    JVM内存和gc机制JVM内存 Java垃圾回收概况 Java GC(Garbage Collection,垃圾收...

网友评论

      本文标题:内存回收(GC)

      本文链接:https://www.haomeiwen.com/subject/jncwoltx.html