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

JVM的几种垃圾收集算法思路

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

JVM的几种垃圾收集算法思路

JVM中垃圾收集算法

分代收集理论(Generation Collection)

弱分代假说(Weak Generation Collection)强分代假说(Strong Generation Collection) 建立在分代收集理论上的收集算法

标记-清除算法(Mark-Sweep)标记-复制算法(Mark-Copying)标记-整理算法(Mark-Compac)

分代收集理论(Generation Collection)

GC收集器应该将Java堆划分为不同的区域,然后对象依据其年龄(经过GC收集的次数),存储到不同的内存区域

该理论建立在两个假说上:弱分代假说和强分代假说。

弱分代假说(Weak Generation Collection)

绝大多数对象的生存周期都很短暂。

因为对象存活的周期较短,所以发生垃圾收集的次数较为频繁,存储此类对象的内存区域,称之为新生代区域。

强分代假说(Strong Generation Collection)

熬过垃圾收集次数越多的对象就越难以消亡。

因为对象存活的周期较长,所以发生垃圾收集的次数较少,存储此类对象的内存区域,称之为老年代区域。

建立在分代收集理论上的收集算法 标记-清除算法(Mark-Sweep)

顾名思义,该算法中包含了标记和清除两个动作。比较有意思的是,标记的是需要清除的,还是标记的是不需要清除的,需要根据具体情况来看,因为标记本身就是额外的开销,自然是越少越好。

比如在回收频繁的内存区域(新生代)中,那么其中的对象肯定回收动作发生很频繁,这个时候我们只标记不需要回收的对象就好了。让GC回收掉那些未被标记的对象。

又比如在内存回收不频繁的区域(老年代),我们只需要标记那些需要被回收的对象就好了,让GC收集器去回收掉就好了。

标记-复制算法(Mark-Copying)

标记-复制算法的思路最开始是半区复制(Semispace Copying),那么何为半区复制呢?
半区复制是:把一块内存,分成大小相等的两块。内存分配只在其中一块上进行。当这一块上的内存用完时,就把这一块上面存活的对象标记出来,复制到另外的一块上去,再把之前那块上使用的内存空间清理掉,以此往复。

优点:假如大部分对象都是可回收的(新生代),那么这样的方式在移动时只需要移动堆顶指针即可,简单有效,快捷,也不用考虑空间碎片的情况

问题很明显:可用的内存直接减少了一半

不过针对可回收对象占大多数的情况,也有其他的 ”半区“复制。比如较为出名的Apple式回收。其思路在内存回收频繁(新生代)的区域,不是把内存分为大小为1:1的两块,而是分为8:1:1的三块内存区域。其中的8 + 1用于内存分配,剩下的1用于复制存活的对象,然后清除掉8+1上的内存空间,将清楚后的 8 + 1 中的1,留着用于下次复制。

当然了你会问:那如果存活的对象总大小大于1呢?那怎么办?这个问题的解决方案是:直接问其他内存区域借一点?问谁?问老年代借一点。对于超出的对象,放入老年代区域就好了。

标记-整理算法(Mark-Compac)

标记-整理算法的思路类似于前文提到的标记-清除,但不同之处在于标记之后,还会整理一次内存区域

具体体现为:将存活的对象往内存边界移动,然后清理掉除存活对象以外的内存区域。

注:本文图片来源–这里.

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

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

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