垃圾回收器

文章详细介绍了Java内存管理中的垃圾回收算法,包括标记-清除、复制、标记-压缩等,以及不同JDK版本中如Serial、ParallelScavenge、CMS、G1、ZGC和Shenandoah等垃圾收集器的工作原理和适用场景。强调了线程数量对效率的影响,以及并发GC在减少STW时间上的努力。
摘要由CSDN通过智能技术生成

回收算法:标记-清除mark-sweep,复制copy,标记-压缩mark-compact。

垃圾回收器:10种。

将内存分为2部分和多部分。

jdk1.8将内存分为2大年代,新生代和老年代。

①新生代

刚刚诞生的对象优先分配给新生代。(刚new出来,年轻的对象)

eden区经过一次的垃圾回收,min或YGC。可清理90%清理掉,留下的放到survivor1

eden区+survivor1扫描,留下的放到survivor2.

eden区              ->  survivor1    -> sruvivor2

比例: 8           ->           1         ->      1

【算法】:采用copy复制算法。

②老年代

经历过垃圾回收的对象(对象经历过垃圾回收,年龄+1,超过一定年龄到老年代)。

内存装不下的时候再垃圾回收一次,清理。

【算法】:标记-清除,标记-压缩。或两者整合。

年轻代满了触发年轻代YGC,老年代满了出发FullGC。

③永久代 ,放class元数据用的。

JDK1.7之前叫perminent area,永久代。

JDK1.8之后叫Metaspace,元空间

都叫方法区。method area。

***********************************垃圾回收演化随着内存大小的不断增长而演进。

1、内存分代模型:

**内存大小几兆到几十兆。

①serial:STW copying collector,单线程GC。

工作在年轻代,业务线程全部停止,垃圾回收器开始清理垃圾。清理完成后,业务线程继续执行。

复制算法的单线程STW垃圾回收,年轻代  老年代。

②serialOld:工作在老年代,单线程STW,采用mark-sweep(标记-清除)算法。

**内存大小几十兆到上百兆或1G。

③parallel scavenge并行多线程,工作在年轻代。PS

④parallelOld并行多线程,工作在老年代。PO

JDK1.8采用的是PS+PO。parallel GC垃圾回收器。

怎么知道使用的是什么垃圾回收器,使用命令查看:

java -XX:+PrintCommandLineFlags -version

**内存大小1G到几十G。

问:是不是线程越多,效率越高?

答:否。线程到达一定阈值之后,效率会遍变低。

一核CPU只能处理一个线程。16核处理16个线程。线程撕裂者,4核8线程,8核16线程。

1W线程会出现排队和切换,切换本身消耗CPU资源的,线程多,上下文的切换contextSwitch,

线程切换所消耗的资源超过了线程运行所占的资源。效率反而会降低。

线程越多,会出现线程等待。

⑤CMS,工作在老年代。年轻代使用serial和parNew(工作在年轻代的多线程)。并发标记清除concurrent mark

CMS不能与PS配合使用的原因是PS不符合它的要求。

存在天生的bug。

**初始标记(找到root根对象,STW时间短)、

**并发标记(三色标记算法,业务线程执行的同时进行并发标记,会出现错标)、

**重新标记(修复标记,STW时间短)、

**并发清理。

Golang采用三色标记算法。

【三色标记算法】:

场景是在并发标记阶段,垃圾回收线程是间隔一段时间运行。每次记录当前标记的位置,Linux采用CFS算法(完全公平算法,不是平均分配),垃圾回收线程运行后记录标记位置。

a.标记追踪对象过程中,已完成追踪到对象和子节点,标记黑色(再次扫描不再标记黑对象)

b.子节点对象非垃圾,已扫描完成,但子子对象还没标记,标记为灰色

c.还没遍历到的节点标记为白对象。

颜色标记放在mark word中。

8字节mark word:锁信息、哈希code、GC(CMS的head记录在此)

4字节classpointer

n个字节的instance state

n个字节的padding

第一种情况:B-D的引用消失。浮动垃圾。无影响,下一次扫描会被标记垃圾。

B->D引用消失,A-D引用增加。D扫描不到,会出现误删情况。

CMS解决方案,把黑色修正为灰色。incremental update(有bug,导致漏标)。依然会产生漏标。

CMS的remak重新标记,还是从头扫描一遍。

⑥parNew

工作在年轻代,多线程。并发标记清除。

⑦G1

JDK1.7与CMS同样,算法不同,采用SATB算法,解决漏标bug。

G1摒弃了年轻代和老年代,内存越来越大,量大处理不来。

物理不分代,逻辑分代。内存区域不固定。

分区算法region。部分回收,连续内存humongous。G1的fullGC。

缺点:一次回收要把年轻代全部回收。YGC全部回收,STW时间长。

⑧ZGC

oracle支持,分页算法,颜色指针colord pointer +  负载屏障load barrier。

不再分年轻代和老年代。每100ms触发一次GC,满的区域回收掉。

⑨Shenandoah

JDK12引入的垃圾回收器,redhat开发的开源。类似ZGC,分页算法。

⑩epsilon

JDK11 版本引入的,什么都不干垃圾回收器。只做记录和跟踪,开发JVM debug使用。

CMS、G1、ZGC、Shenandoah,都使用concurrent GC垃圾回收器

GC线程和业务线程可以同时运行。

2、内存不分代模型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值