上篇文章深入浅出JVM(十一)之如何判断对象“已死”曾经深入浅出的解析JVM是如何评判对象不再应用,不再应用的对象将变成“垃圾”,期待回收

垃圾回收算法有多种,实用于不同的场景,不同的垃圾收集器应用不同的算法

本篇文章将围绕垃圾回收算法,深入浅出的解析垃圾回收分类以及各种垃圾回收算法

垃圾回收算法

垃圾回收分类

垃圾收集器有着多种GC形式,不同的GC形式有本人的特点,回收的堆内存局部也不同

堆内存分为新生代和老年代,新生代存储“年老”的对象,老年代存储“老”或内存大的对象,对象年龄由经验多少次GC来判断

其中整堆收集时不仅会回收整个堆还会回收元空间(间接内存)

  • 局部收集(Partial GC): 收集指标是局部空间

    • 新生代收集(Minor GC/ Young GC):收集新生代Eden、Survive to、Survive from区
    • 老年代收集(MajorGC/Old GC):收集老年代
    • 混合收集(Mixed GC):收集整个新生代和局部老年代
  • 整堆收集(Full GC): 整个堆 + 元空间

标记-革除算法

Mark-Sweep

标记:从GCRoots开始遍历援用链,标记所有可达对象 (在对象头中标记)

革除:从堆内存开始线性遍历,发现某个对象没被标记时对它进行回收

标记-革除算法实现简略、不须要扭转援用地址,然而须要两次遍历扫描效率不高,并且会呈现内存碎片

留神:这里的革除并不是真正意义上的回收内存,只是更新闲暇列表(标记这块内存地址为闲暇,后续有新对象须要应用就笼罩)

复制算法

Copying

Survive辨别为两块容量一样的Survive to区和Survive from区

每次GC将Eden区和Survive from区存活的对象放入Survive to区,此时Survive to区改名为Survive from区,原来的Survive from区改名为Survive to区 保障Survive to区总是闲暇的

如果Survive from区的对象通过肯定次数的GC后(默认15次),把它放入老年代

流程图

留神:图中的dean为Eden区(写错)

留神:最终的survive from区存活对象占用的内存应该是(那两块蓝色)挨着一起的,图中为了标识字离开来了

复制算法不须要遍历,并且不会产生内存碎片,然而会节约survive区一半的内存,挪动对象时须要STW暂停用户线程,并且复制后会扭转援用地址(hotspot应用间接指针拜访,还要扭转栈中reference执行新援用地址)

如果复制算法中对象存活率太高会导致非常耗费资源,因而个别只有新生代才应用复制算法

标记-整顿算法

Mark-Compact

标记:从GCRoots开始遍历援用链,标记所有可达对象(在对象头中标记) (与标记-革除算法统一)

整顿:让所有存活对象往内存空间一端挪动,而后间接清理掉边界以外的所有内存

标记-整顿算法不会呈现内存碎片也不会节约空间,然而效率低(比标记-革除还多了整顿性能),挪动对象导致STW和扭转reference指向

如果不挪动对象会产生内存碎片,内存碎片过多,将无奈为大对象分配内存

还有种办法:屡次标记-革除,等内存碎片多了再进行标记-整顿

分代收集算法

标记革除mark-sweep复制copying标记整顿mark-compact
速度
GC后是否须要挪动对象不挪动对象挪动对象挪动对象
GC后是否存在内存碎片存在内存碎片不存在内存碎片不存在内存碎片

须要挪动对象 意味着 要扭转改对象援用地址 也就是说要扭转栈中reference指向改对象的援用地址,并且会产生STW进展用户线程

当空间中存在大量内存碎片时,可能导致大对象无奈存储

分代收集算法 : 看待不同生命周期的对象能够采纳不同的回收算法(不同场景采纳不同算法)

年老代: 对象生命周期短、存活率低、回收频繁,采纳复制算法,高效

老年代: 对象生命周期长、存活率高、回收没年老代频繁,采纳标记-革除 或混用 标记-整顿

增量收集算法

mark-sweep、copying、mark-compact算法都存在STW,如果垃圾回收工夫很长,会重大影响用户线程的响应

增量收集算法: 采纳用户线程与垃圾收集线程交替执行

增量收集算法可能进步用户线程的响应工夫,但存在GC、用户线程切换的开销,升高了吞吐量,GC老本变大

分区算法

堆空间越大,GC工夫就会越长,用户线程响应就越慢

分区算法: 将堆空间划分为间断不同的区,依据要求的进展工夫正当回收n个区,而不是一下回收整个堆

每个区独立应用,独立回收,依据能接受的进展工夫管制一次回收多少个区

G1收集器以及两块低提早收集器Shenandoah、ZGC就应用到这种分区算法

总结

本篇文章围绕垃圾回收算法,深入浅出解析垃圾回收分类、标记革除、复制、标记整顿、分代收集、增量收集、分区算法等多种算法

从垃圾回收空间上划分能够分为Full GC回收整个堆加上元空间、Minor GC回收新生代、major GC回收老年代、mixed GC回收新生代加老年代

标记革除算法会遍历援用链标记可达对象从而清理不可达对象,会产生内存碎片,速度个别

复制算法不会产生内存碎片,并且速度很快,然而会节约survivor区一半空间,并且会挪动对象

标记整顿算法在标记清理根底上减少整顿性能,不会产生内存碎片,但会挪动对象,速度慢

不同的算法有不同的特点,应答新生代能够应用复制算法,应答老年代能够应用标签革除/整顿算法

增量收集应用GC、用户线程交替执行,尽管升高用户响应,但线程切换、吞吐量降落会减少GC老本

分区算法将堆内存划分为多个区,依据可能接管的进展工夫来回收性价比高的多个区,进展工夫既在可能接管工夫内,又可能回收性能比高的区

最初(一键三连求求拉~)

本篇文章将被支出JVM专栏,感觉不错感兴趣的同学能够珍藏专栏哟~

本篇文章笔记以及案例被支出 gitee-StudyJava、 github-StudyJava 感兴趣的同学能够stat下继续关注喔\~

有什么问题能够在评论区交换,如果感觉菜菜写的不错,能够点赞、关注、珍藏反对一下\~

关注菜菜,分享更多干货,公众号:菜菜的后端私房菜

本文由博客一文多发平台 OpenWrite 公布!