GC之垃圾对象判定及回收机制

如何判定对象为垃圾对象

1、引用计数法
2、可达性分析法
这里写图片描述
引用分析法

原理:在对象中添加一个引用计数器,当有地方引用这个对象的时候,这个引用计数器的值就+1,让引用失效(把对象的值制为空)的时候,这个计数器的值就-1。

优点:实现简单,判定效率高

缺点:如果①断开后,这个对象的引用计数器还是大于0,就像如上图所示,object1对象除了被栈中引用之外,对象object2也引用了object1对象,那么他的引用计数器就算①断了还是大于0,这时候垃圾回收器就认为这个对象存活,并不会对object1和object2对象进行回收。简单来说就是当对象存在循环引用的情况下是没法判断是否存活的。

可达性分析法: 一般用的就是这个算法

原理:先定义一个垃圾回收的根节点(GCROOT),然后沿着这个根节点找下去,凡是找不到的对象都被认为是垃圾对象。这样一来,上图中的①一旦断了那么②就会立马被标记为垃圾对象

GCROOT对象:
1、虚拟机栈
2、方法区的类属性所引用的对象
3、方法区中常量所引用的对象
4、本地方法栈中引用的对象

垃圾回收机制

1、标记-清除算法
2、赋值算法
3、标记-整理-清除算法
4、分代算法

标记-清除算法
这里写图片描述
原理: 将标记为垃圾的对象直接进行回收

存在的问题:

1、效率问题
2、空间问题:这样回收的堆内存是不连续的

复制算法: 针对于新生代
这里写图片描述
原理: 使用一般的内存,当进行垃圾回收的时候,将①中未被标记为垃圾的对象复制到②中,然后回收①中的所有内存。

优点:提高了标记清除算法的性能、效率

缺点:内存区域使用的只有一半,极大浪费了内存区域。

解决方法: 将堆内存中的新生代进行分区,分为一个Eden(占大约80%),两个Survivor(每个占10%左右) - - -这可能就是新生代为什么要分区的原因(个人猜想0.0)

解决原理: 当创建的对象使得Eden和Survivor1区域占满,然后进行垃圾回收的时候,一般默认为只有10%的对象将会被存活下来(如果超过10%的对象存活下来的话,将要进行内存担保),将这10%存活下来的对象使用复制算法存入Survivor2区域中,原来的Eden和Survivor1区域内存将全部回收,第二次创建对象将存放入Eden和Survivor2中,第二次gc时,Survivor1区域是全空内存,将第二次gc存活下来的对象复制到Survivor1中。这样的使用就浪费了10%的内存,是可以接受的。

标记-整理-清除算法: 针对于老年代
这里写图片描述
原理: 刚进行gc的时候,被标记的内存将向一个方向移动,未被标记的内存向另一个方向移动,这样一来就直接回收标记区的内存就ok

分代收集算法: 标记整理算法和复制算法的结合,根据内存的不同分代使用不同的垃圾回收算法,大致就是在新生代使用复制算法,在老年代使用标记整理算法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值