Jvm之垃圾收集器与内存分配策略(四)

各款经典收集器之间的关系

 “并发”和“并行”

        并行(Parallel):并行描述的是多条垃圾收集器线程之间的关系,说明同一时间有多条这样的线程在协同工作,通常默认此时用户线程是处于等待状态。

        ·并发(Concurrent):并发描述的是垃圾收集器线程与用户线程之间的关系,说明同一时间垃圾收集器线程与用户线程都在运行。由于用户线程并未被冻结,所以程序仍然能响应服务请求,但由于垃圾收集器线程占用了一部分系统资源,此时应用程序的处理的吞吐量将受到一定影响。


一,Serial收集器(新生代)

Serial收集器是最基础、历史最悠久的收集器

特点:

1.单线程工作的收集器

2.“Stop The World”(它进行垃圾收集时,必须暂停其他所有工作线程,直到它收集结束

适合场景:

是HotSpot虚拟机运行在客户端模式下的默认新生代收集器

优点:简单高效

        对于单核处理 器或处理器核心数较少的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以 获得最高的单线程收集效率。


二,ParNew收集器(新生代)

ParNew收集器是Serial收集器的多线程并行版本

成也萧何败也萧何

        CMS收集器。这款收集器是HotSpot虚拟机中第一款真正意义上支持并发的垃圾收集器,它首次 实现了让垃圾收集线程与用户线程(基本上)同时工作。

 ParNew收集器首选原因是因为

除了Serial收集器外,目前只有它能与CMS 收集器配合工作。

但是jdk9以后

更先进的G1收集器带着CMS继承者和替代者的光环登场。CMS收集器没落

并且取消了ParNew加 Serial Old以及Serial加CMS


三,Parallel Scavenge收集器(新生代)

又称“吞吐量优先收集器”

关注点:

CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间

Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量

 吞吐量计算公式:

 

Parallel Scavenge收集器与ParNew收集器的区别

自适应调节策略


四,Serial Old收集器(老年代)

        Serial Old是Serial收集器的老年代版本,它同样是一个单线程收集器,使用标记-整理算法。

主要意义:

1.供客户端模式下的HotSpot虚拟机使用。

2.就是作为CMS 收集器发生失败时的后备预案,在并发收集发生Concurrent Mode Failure       时使用。


五,Parallel Old收集器(老年代)

Parallel Old是Parallel Scavenge收集器的老年代版本,也是jdk8默认老年代收集器,支持多线程并发收集,基于标记-整理算法实现。

“吞吐量优先“


六,CMS收集器(老年代)

最短回收停顿时间的收集器,采用标记-清除算法

标记-清除算法步骤

1)初始标记(CMS initial mark)

2)并发标记(CMS concurrent mark)

3)重新标记(CMS remark)

4)并发清除(CMS concurrent sweep)

初始标记重新标记这两个步骤仍然需要“Stop The World”

1.初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快;

2.并发标记阶段就是从GC Roots的直接关联对象开始遍历整个对 象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行;

3.重新标记阶段则是为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录。

4.并发清除阶段清理删除掉标记阶段判断的已经死亡的对象,由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。

优点: 

并发收集、低停顿

回收阶段

CMS收集器的内存回收过程是与用户线程一起并发执行的

缺点:

        1.虽然不会导致用户线程停顿,但却会因为占用了一部分线程(或者说处理器的计 算能力)而导致应用程序变慢,降低总吞吐量(如果应用本来的处理器负载就很高,可能导致效率大幅度降低

        2.无法处理“浮动垃圾”问题

        3.收集结束时会有大量空间碎片产生

        浮动垃圾:在CMS的并发标记和并发清理阶 段,用户线程是还在继续运行的,程序在运行自然就还会伴随有新的垃圾对象不断产生,但这一部分 垃圾对象是出现在标记过程结束以后,CMS无法在当次收集中处理掉它们,只好留待下一次垃圾收集 时再清理掉。这一部分垃圾就称为“浮动垃圾” 

jdk9以后被抛弃 


七, Garbage First收集器

        Garbage First(简称G1)收集器是垃圾收集器技术发展历史上的里程碑式的成果,它开创了收集 器面向局部收集的设计思路和基于Region的内存布局形式

 jdk9之后成为服务端模式下的默认垃圾收集器

        停顿时间模型:停顿时间模型的意思是能够支持指定在一个长度为M毫秒的时间片段 内,消耗在垃圾收集上的时间大概率不超过N毫秒这样的目标,这几乎已经是实时Java(RTSJ)的中 软实时垃圾收集器特征了。

停顿时间模型的实现:

        G1不再坚持固定大小以及固定数量的 分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以 根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间,使用Region划分内存空间,以及具有优先级的区域回收方式,保证了G1收集器在有限的时间内获 取尽可能高的收集效率

存储大对象的的Humongous区域:

1.G1认为只要大小超过了一个 Region容量一半的对象即可判定为大对象。

2.超过了整个Region容量的超级大对象, 将会被存放在N个连续的Humongous Region之中

 跨Region引用对象如何解决:

        每个Region都维护有自己的记忆集,这些记忆集会记录下别的Region 指向自己的指针,并标记这些指针分别在哪些卡页的范围之内。

在并发标记阶段如何保证收集线程与用户线程互不干扰地运行? 

CMS收集器采用增量更新算法实现,

G1 收集器则是通过原始快照(SATB)算法来实现的。

步骤 

        初始标记(Initial Marking):仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS 指针的值,让下一阶段用户线程并发运行时,能正确地在可用的Region中分配新对象。这个阶段需要 停顿线程,但耗时很短,而且是借用进行Minor GC的时候同步完成的,所以G1收集器在这个阶段实际 并没有额外的停顿。

         并发标记(Concurrent Marking):从GC Root开始对堆中对象进行可达性分析,递归扫描整个堆 里的对象图,找出要回收的对象,这阶段耗时较长,但可与用户程序并发执行。当对象图扫描完成以 后,还要重新处理SATB记录下的在并发时有引用变动的对象。

        ·最终标记(Final Marking):对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留 下来的最后那少量的SATB记录。

         ·筛选回收(Live Data Counting and Evacuation):负责更新Region的统计数据,对各个Region的回 收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个Region 构成回收集,然后把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉整个旧 Region的全部空间。这里的操作涉及存活对象的移动,是必须暂停用户线程,由多条收集器线程并行 完成的。

        G1收集器除了并发标记外,其余阶段也是要完全暂停用户线程的, 换言之,它并非纯粹地追求低延迟,官方给它设定的目标是在延迟可控的情况下获得尽可能高的吞吐 量,所以才能担当起“全功能收集器”的重任与期望。

和CMS比较

优势:

1.创意上指定最大停顿时间、分Region的内存布局、按收益动 态确定回收集

2.整体上使用”标记-整理算法“,局部上”标记—复制“,导致回收过程中不会产生内存碎片问题

劣势:

垃圾收集产生的内存占用程序运行时的额外执行负载都比CMS要高

总结:

        目前在小内存应用上CMS的表现大概率仍然要会优于G1,而在大内存应用上G1则大多能发挥其 优势,这个优劣势的Java堆容量平衡点通常在6GB至8GB之间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值