关于GC垃圾回收及其算法的一点思考

14 篇文章 0 订阅
6 篇文章 0 订阅

在学过java一些有关GC以及相关算法后,对一些概念以及GC与垃圾回收算法的关系有点混乱,觉得有必要好好总结一下了,虽然GC诞生的时间比java早,并且GC并不是java语言所独有的,但垃圾收集机制是java语言的招牌能力,极大的提高了开发效率,并且成为现代语言的标配,因此我们必须深入学习java的垃圾收集机制

1.什么是GC,什么是垃圾,为什么需要GC

GC是指垃圾回收机制,所谓垃圾是指在运行程序中没有任何指针指向的对象

当一个对象不能再被复后续程序所引用到时,这个对象所占用的内存空间就没有存在的意义了,java虚拟机会不定时的去检测内存中这样的对象,然后回收这块内存空间。这也是垃圾和GC的关系,一个java程序在运行之中是会不断产生对象的,并且绝大多数对象生命周期很短,很容易变成垃圾占用大量内存空间,并且这些空间会一直保留到应用程序结束

对于高级语言来说,如果不进行垃圾回收,内存迟早会被消耗完,这种情况下就非常有必要进行GC,垃圾回收除了释放没用的对象,还进行内存中内存碎片的清理(对应着垃圾回收算法中的标记-整理算法),以便将整理出来的内存分配给新的对象,没有GC就不能保证程序的正常进行

2.GC采取分代收集算法执行垃圾回收

在我的博客垃圾收集算法-如何判定对象死亡中详细阐述了如何判断对象死亡,其中的可达性算法通过GC Roots按照从上至下的方式搜索被根对象集合所链接的对象是否可达,来判断对象是否可以被回收,并且应用在标记-清除算法和标记-整理算法中的标记阶段

标记-清除算法,标记-整理算法,标记-复制算法这三种算法各有优缺点,不能说它们中的哪一个是最好的算法,只有在合适的场景中发挥各自的优势,分代收集算法应运而生

接着往下,我们都知道java对象的生命周期长短不一,绝大多数对象朝生夕死和熬过多次收集的难以消亡的对象,针对这一现象发展出两个假说:

  • 弱分代假说
  • 强分代假说

这两个假说共同奠定了多款垃圾收集器的的一致设计原则:垃圾收集器应该将java堆划分成不同的区域,然后将回收对象根据其年龄分配到不同的区域中存储,这就是分代收集理论

注意:在《Java虚拟机规范》中指出:所有的对象实例以及数组都应该在对上分配,仅仅是指出了堆因该存储什么,而没有进一步将堆细分为年轻代,老年代,Eden,Survivor区了,实际上,这些将堆更细致的划分是一部分垃圾收集器的设计风格而已,目的是根据不同生命周期的对象划分出不同的内存区域,运用不同垃圾收集算法采取不同收集方式提高回收效率,因此并不是虚拟机实现的堆的内存布局,更不是《Java虚拟机规范》中堆Java堆的划分

在Java堆中划分出不同区域之后,垃圾收集器可以每次只回收其中一个或某些部分的区域,也就产生了Minor GC,Major GC,Full GC这样的回收类型的划分
如上所述,HotSopt虚拟机也是基于分代的概念,其GC所使用的内存回收算法必须结合年轻代和老年代各自的特点

  • 年轻代的特点这里就不赘述了,按照分代思想,由于此区域对象生命周期短暂,存活率低,回收频繁,那么标记-复制算法在这种情况下可以发挥出它的优势,因此很适用于年轻代的垃圾回收,且该算法的内存利用率不高的问题也被hotspot中的两个survivor涉及所缓解
  • 对于老年代,该区域较大,对象生命周期长,存活率搞,回收频率较低,在这种情况下复制算法显然不适用,因此采取的是标记清除或者标记清除和标记整理的混合实现

总结的话来说就是:分代思想被现有的虚拟机广泛使用,几乎所有垃圾回收器都区分新生代和老年代,不同区域采取不同收集方式,根据分代运用不同算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值