垃圾收集器

Serial

Serial收集器是Hotspot运行在Client模式下的默认新生代收集器, 它在进行垃圾收集时,会暂停所有的工作进程,用一个线程去完成GC工作

 

 

特点:简单高效,适合jvm管理内存不大的情况(十兆到百兆)。

Parnew

ParNew收集器其实是Serial的多线程版本,回收策略完全一样,但是他们又有着不同。

 

 

 

我们说了Parnew是多线程gc收集,所以它配合多核心的cpu效果更好,如果是一个cpu,他俩效果就差不多。(可用-XX:ParallelGCThreads参数控制GC线程数)

Cms

CMS(Concurrent Mark Sweep)收集器是一款具有划时代意义的收集器, 一款真正意义上的并发收集器, 虽然现在已经有了理论意义上表现更好的G1收集器, 但现在主流互联网企业线上选用的仍是CMS(如Taobao),又称多并发低暂停的收集器。

 

 

由他的英文组成可以看出,它是基于标记-清除算法实现的。整个过程分4个步骤:

  1. 初始标记(CMS initial mark):仅只标记一下GC Roots能直接关联到的对象, 速度很快

  2. 并发标记(CMS concurrent mark: GC Roots Tracing过程)

  3. 重新标记(CMS remark):修正并发标记期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录

  4. 并发清除(CMS concurrent sweep: 已死对象将会就地释放)

可以看到,初始标记、重新标记需要STW(stop the world 即:挂起用户线程)操作。因为最耗时的操作是并发标记和并发清除。所以总体上我们认为CMS的GC与用户线程是并发运行的。

优点:并发收集、低停顿

缺点:

  1. CMS默认启动的回收线程数=(CPU数目+3)*4

    当CPU数>4时, GC线程最多占用不超过25%的CPU资源, 但是当CPU数<=4时, GC线程可能就会过多的占用用户CPU资源, 从而导致应用程序变慢, 总吞吐量降低.

  2. 无法清除浮动垃圾(GC运行到并发清除阶段时用户线程产生的垃圾),因为用户线程是需要内存的,如果浮动垃圾施放不及时,很可能就造成内存溢出,所以CMS不能像别的垃圾收集器那样等老年代几乎满了才触发,CMS提供了参数-XX:CMSInitiatingOccupancyFraction来设置GC触发百分比(1.6后默认92%),当然我们还得设置启用该策略-XX:+UseCMSInitiatingOccupancyOnly

  3. 因为CMS采用标记-清除算法,所以可能会带来很多的碎片,如果碎片太多没有清理,jvm会因为无法分配大对象内存而触发GC,因此CMS提供了-XX:+UseCMSCompactAtFullCollection参数,它会在GC执行完后接着进行碎片整理,但是又会有个问题,碎片整理不能并发,所以必须单线程去处理,所以如果每次GC完都整理用户线程stop的时间累积会很长,所以XX:CMSFullGCsBeforeCompaction参数设置隔几次GC进行一次碎片整理(默认为0)。

G1

同优秀的CMS垃圾回收器一样,G1也是关注最小时延的垃圾回收器,也同样适合大尺寸堆内存的垃圾收集,官方也推荐使用G1来代替选择CMS。G1最大的特点是引入分区的思路,弱化分代的概念,合理利用垃圾收集各个周期的资源,解决了其他收集器甚至CMS的众多缺陷。

 

 

 

因为每个区都有E、S、O代,所以在G1中,不需要对整个Eden等代进行回收,而是寻找可回收对象比较多的区,然后进行回收(虽然也需要STW操作,但是花费的时间是很少的),保证高效率。

新生代收集

G1的新生代收集跟ParNew类似,如果存活时间超过某个阈值,就会被转移到S/O区。

年轻代内存由一组不连续的heap区组成, 这种方法使得可以动态调整各代区域的大小

老年代收集

分为以下几个阶段:

  1. 初始标记 (Initial Mark: Stop the World Event)

    在G1中, 该操作附着一次年轻代GC, 以标记Survivor中有可能引用到老年代对象的Regions.

  2. 扫描根区域 (Root Region Scanning: 与应用程序并发执行)

    扫描Survivor中能够引用到老年代的references. 但必须在Minor GC触发前执行完

  3. 并发标记 (Concurrent Marking : 与应用程序并发执行)

    在整个堆中查找存活对象, 但该阶段可能会被Minor GC中断

  4. 重新标记 (Remark : Stop the World Event)

    完成堆内存中存活对象的标记. 使用snapshot-at-the-beginning(SATB, 起始快照)算法, 比CMS所用算法要快得多(空Region直接被移除并回收, 并计算所有区域的活跃度).

  5. 清理 (Cleanup : Stop the World Event and Concurrent)

    在含有存活对象和完全空闲的区域上进行统计(STW)、擦除Remembered Sets(使用Remembered Set来避免扫描全堆,每个区都有对应一个Set用来记录引用信息、读写操作记录)(STW)、重置空regions并将他们返还给空闲列表(free list)(Concurrent)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值