栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JVM垃圾回收的分代收集思想

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JVM垃圾回收的分代收集思想

在深入理解垃圾回收思想的时候,也要了解一下分代收集理论。

分代收集理论

这个理论主要是建立在两个分代假说之上的:

    弱分代假说(Weak Generational Hypothesis):绝大多数对象都是朝生夕灭的。强分代假说(Stong Generational Hypothesis):熬过越多次垃圾收集过程的对象就越难以死亡。

这两个部分共同奠定了后面很多的垃圾收集器的基本设计原则:收集器应该将Java堆划分出不同的区域,然后将回收对象依据年龄分配到不同的区域进行存储,针对不同的区域,又进行不同的垃圾收集。

但在最后也还出现了一个问题,在进行一次只限于新生代区域的收集(Minor GC),但新生代中的对象完全有可能被老年代所引用的,为了找出该区域中的存活对象,就不得不在固定的GC Roots之外,再额外遍历整个老年代所有对象来确保可达性结果的正确性,反过来也是一样的。这种在理论上是可行的,但实际上会对内存回收带来很大的性能负担。

所以就有了第三条经验法则:

    跨代引用假说(Intergenerational Reference Hypothesis):跨代引用相对于同代引用来说仅占极少数。

存在互相引用关系的两个对象,是一个倾向于同时生存或者同时消亡的。

依据这条假说,我们就不再为了少量的跨代引用去扫描整个老年代,也不必浪费空间专门记录每一个对象是否存在哪些跨代引用,只需要在新生代上建立一个全局的数据结构(记忆集),这个结构把老年代划分为若干个小块,标识出老年代的那一块内存会存在跨代引用。
当在这之后再发生Minor GC时,只有包含了跨代引用的小块内存里的对象才会被加入GC Roots中进行扫描。

为什么使用分代收集

那在java虚拟机中为什么要对垃圾的回收使用分代的收集的方法。

在垃圾回收的算法中,并没有一种算法就可以完全替代其他的算法,它们都具有自己独特的优势和特点。分代收集的思想就应运而生。

分代收集,是基于这样的事实:
不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率。一般把Java堆分为新生代和老年代,这样就可以根据各个年代的特点来使用不同的回收算法,以提高垃圾回收的效率。

在Java程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关的。
比如Http请求中的Session对象、线程、Socket连接,这类对象根业务直接挂钩,因此生命周期都是比较长的。
但是还有一些对象,主要是程序运行过程中生成的临时变量,这些对象生命周期会比较短。比如:String对象,由于其不变类的特性,系统会产生大量的这些对象,有些对象甚至只用一次即可回收。

在目前几乎所有的GC都采用分代收集算法执行垃圾回收的

在主流的HotSpot中,基于分代的概念,GC所使用的内存回收算法必须结合年轻代和老年代各自的特点。

针对不同的区域进行分区收集,进而来提高收集效率。

年轻代(Young Gen)
特点:区域相对老年代来说比较小,对象的生命周期较短、存活率低,回收频繁。

这种情况复制算法的回收整理、速度是最快的。复制算法的效率只和当前存活对象大小相关,因此很适合用于年轻代的回收。而复制算法内存利用率不高的问题,通过hotspot中的两个survivor的设计得到缓解。

老年代(Tenured Gen)
特点:区域较大,对象的声明周期长,存活率高,回收没有年轻代的频率高。

这种情况存在着大量的存活率高的对象,而复制算法明显是很不合理的。一般都是采用标记 - 清除或者 标记- 整理的混合实现。

    Mark阶段的开销与存活对象的数量成正比。Sweep阶段的开销与所管理区域的大小成正相关。Compact阶段的开销与存活对象的数据成正比。

而分代的思想被现有的虚拟机广泛使用。几乎所有的垃圾回收器都区分新生代和老年代。

上一篇: >>>> 垃圾回收算法

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/762492.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号