常见垃圾收集器介绍及内存分配回收策略(本章无G1以及ZGC)

常见垃圾收集器介绍及内存分配回收策略

  • 前言

这里会为大家简单介绍市面上比较主流的垃圾收集器以及内存分配回收的一些策略,对于单个垃圾收集器的介绍,会放在之后单独写文章详细分析,有说的不严谨的地方希望大家留言批评指正

  • 垃圾收集器组合示意图

这里是引用
各种垃圾收集器可以两两配合搭配使用,一个作为新生代垃圾回收,一个作为老年代垃圾回收

  • Serial垃圾收集器(新生代)

这里是引用
首先为大家用一张图来表示Serial收集器的执行流程,默认使用的是标记-复制算法,很明显的可以看出这个垃圾收集器的执行会在所有用户线程到达安全的的时候,通过暂停所有用户线程,然后调用GC线程进行新生代的垃圾回收,重点说明他进行GC的时候会STW(Stop The World),但是虽然是单线程的,但是不能说他是毫无用处的,对于单核处理器或者处理器核心数较少的情况,由于这款垃圾收集器没有线程交互的开销,线程可以专心进行垃圾收集,以获得最高的单线程收集效率

  • ParNew垃圾收集器(新生代)

这里是引用
上图是ParNew垃圾收集器在新生代收集的示意图,默认使用的是标记-复制算法,其实可以明显的看出,和Serial收集器的明显区别就是他在用户线程到达安全的的时候,会启动多条GC线程进行垃圾收集,这里他的设计并没有什么创新之处,但是除了Serila收集器,他是唯一一个能与CMS配合的垃圾收集器,所以这确立了他的位置

  • Paraller Scavenge垃圾收集器(新生代)

Paraller Scavenge垃圾收集器同样是一款新生代垃圾收集器,默认是用的标记-复制算法,对新生代GC时多线程的进行垃圾回收,但是他与上面说的两款垃圾收集器最大的创新点在于,他关注的是吞吐量,这里给大家一个图,说明什么是吞吐量
在这里插入图片描述
这里控制吞吐量主要就是设置两个参数
-XX:MaxGCPauseMillis 这个参数允许的是一个大于0的毫秒数,收集器会尽力保证内存回收的时间不超过这个时间,但是这里设置的时间是以牺牲吞吐量和新生代空间做代价的,所以不要认为设置的越小垃圾收集就越快
-XX:GCTimeRatio 这个参数设置的是0-100的证书,就是垃圾收集时间占总时间的比例

  • Serial Old垃圾收集器(老年代)

这里是引用
上图就是Serial Old垃圾收集器的执行方法,默认是使用的标记-整理算法,对老年代进行单线程的垃圾回收,这个要着重注意一个点,他还被认为是CMS收集器垃圾回收失败之后的备选方案,这个在讲CMS的时候会进行说明

  • Parallel Old收集器(老年代)

这里是引用
如上图所示,就是一个可供老年代进行多线程收集的垃圾收集器,默认使用标记-整理算法

  • CMS收集器(老年代)

是一种追求最短回收停顿时间的垃圾回收器,默认使用的是标记-清除算法,最终的目的就是希望系统停顿时间尽可能的短,给用户带来良好的交互体验整体氛围四个步骤
在这里插入图片描述

初始标记:仅仅是标记GC ROOTS能关联到的对象,速度很快
并发标记:从GC ROOTS的直接关联对象开始遍历整个对象图,时间较长,可以和用户线程同步执行,但是这过程同时会因为用户线程正在执行,导致标记变动,这里CMS使用的增量更新的方式解决,G1使用的SATB解决,对于这个过程可能出现的问题以及解决方案,也就是三色标记,后期会专门出一篇文章讲解一下
重新标记:就是为了解决并发标记阶段,因为用户线程继续执行产生的标记变动的情况,这里小号的时间会比初始标记的时间稍长但是会远远地低于并发标记的时间
并发清理:最终就是清除掉标记阶段已经死亡的对象

CMS同样会存在一些缺点,CMS无法清除浮动垃圾,因为并发标记和并发清理阶段,有可能在标记结束之后产生的垃圾,在这一次是不能够进行清除的,只能到下一次垃圾收集才能进行回收,另外就是,因为并发标记和并发清理阶段要和用户线程同时运行,所以就需要预留出足够的内存空间给用户线程使用,这是说明CMS不能像其他垃圾收集器一样在老年代快要满的时候进行垃圾回收,在JDK5的时候在老年代使用了68%的空间时就会被激活,在JDK6的时候默认提升到了92%,但是又有了另一种风险,在CMS运行期间预留内存不能满足分配对象需要,这就会出现一次并发失败,这时候虚拟机会启动后备方法,冻结用户线程执行,改用Serial old收集器对老年代进行回收

  • 内存分配与回收策略

对象优先在Eden分配:大多数情况,对象在新生代的Eden区进行分配,放Eden区没有足够的内存进行分配的时候,虚拟机将进行一次Minor GC
大对象直接进入老年代:大对象就是指需要大量连续内存空间的Java对象,在分配空间的时候,它容易导致内存空间还有不少,但是提前触发垃圾收集,并且,在Eden和Survivor来回赋值会产生大量内存赋值操作,所以有规定大对象直接进入老年代
长期存活的对象进入老年代:大多数垃圾收集器都是用分代收集的思想来管理堆内存,对象通常在Eden产生,如果进行了第一次Minor GC依旧存活的话,年龄被设置为1,然后当每次在Survivor存活就增加一岁,达到阈值(默认15)就会被晋升到老年代,这个可以通过-XX:MaxTenuringThreshold设置
动态对象年龄判定:如果在Survivor空间中相同年龄的所有对象总和大于Survivor的一半,那么就不需要等待年龄到达阈值就进入到老年代

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值