关于垃圾回收

1. GC发生在什么时候?
  • GC主要分为young/minor gc和full gc。
    • young gc触发的时机是:在新生代的Eden区满了之后,会发生young gc,同时在young gc时会有一部分存活的对象晋升到old gen中,所以在young gc后,old gen占用量会提升一些。
    • full gc触发的时机涉及到空间分配担保。在进行young gc前,虚拟机会先检查old gen剩余空间是否 > young gen所有对象的总空间
      • 如果 > ,说明old gen有足够空间,那么进行young gc是安全的,所以直接进行young gc。
      • 如果 < ,说明old gen空间不足,那么虚拟机会先查看HandlePromotionFailure参数是否允许担保失败。
        • 如果允许,则计算前面每次回收晋升到old gen对象大小的平均值,将这个平均值与old gen的剩余空间进行比较
          • 如果old gen剩余空间 > 平均值,说明这个时候可以尝试进行young gc,因为有可能old gen可以担保成功(前提是HandlePromotionFailure设置允许担保失败)。
          • 如果old gen剩余空间 < 平均值,说明这个时候进行young gc很可能会担保失败,所以必须进行full gc。
        • 如果不允许,则进行full gc。
2. GC是对哪些内存进行了回收?

gc是对不可用的对象进行回收,判断一个对象是否不可用采用的是可达性分析算法,具体的做法就是:从“GC Roots”开始,向下搜索,如果从GC Roots到某个对象不可达,那么这个对象就是不可用的,会被判定为是可回收的对象。

不过这些对象也不是立即就会被回收,真正宣告一个对象死亡需要至少经历两次标记过程。

  • 在通过可达性分析后发现某个对象没有和GC Roots相连接的引用链,那么这个对象会被第一次标记并且进行一次筛选。
    • 筛选的条件是:该对象是否需要执行finalize()方法
      • 如果该对象没有覆盖finalize()方法 or finalize()方法已被虚拟机调用过,则无需执行finalize()方法。
      • 否则,需要执行finalize()方法
        • 在执行finalize()方法中该对象可以进行自救,即尝试将自己与引用链上任何一个对象建立关联(比如将自己赋值给某个类变量 or 对象的成员变量)
          • 如果自救成功,在第二次标记时,该对象将从“即将回收”的集合中被移出。
          • 如果自救失败,那么基本上这个对象就会真的被回收。
3. 为什么GC要分代回收

对传统的GC来说,一般都需要“stop the world”,所以要想提高GC的效率,需要下大功夫在减少“stop the world”的时间,如果每次都要对整个堆回收,想必耗费时间肯定较长,所以我们考虑可以每次只回收一部分,从而加快回收的效率。

分代式GC就是这么做的,在基于一个基本假设(大
多数对象都是朝生夕死的-这是对过往的很多应用进行行为分析后得出的假设)的前提下,根据对象的存活周期的不同可以将内存划分为几块。

一般是将Java heap划分为young gen和old gen:让大部分对象都在young gen中创建,然后频繁回收young gen,那么大部分垃圾都能在young gen中回收掉,对应young gen的特点-大部分对象存活率较低,所以可以采用复制算法,因为对象存活率较低,采用复制算法不需要执行较多赋值操作,并且也几乎不会产生内存碎片。而在old gen中,因为对象存活率较高,如果使用复制算法的话,会执行较多的复制操作,从而导致效率降低,并且采用复制算法需要一定的额外空间做担保,所以old gen不能采用复制算法,而是采用的标记-整理算法。

可以看到,我们可以根据某代的特点针对性的采用合适的算法来收集,从而进一步提高GC的效率,这也是GC分代的原因之一。


所以,总结一下,GC分代的好处主要有:
1. 每次可以只回收一部分heap,从而减少了“stop the world”的时间。
2. 分代后可以针对每代的特点采用对应的收集算法,从而提高GC效率

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值