博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JVM——垃圾收集器(二)——垃圾收集算法
阅读量:5740 次
发布时间:2019-06-18

本文共 1238 字,大约阅读时间需要 4 分钟。

hot3.png

目录:

1.标记-清除算法

2.复制算法

3.标记-整理算法

4.分代收集算法

 

1.标记-清除算法

最基础的收集算法。如同他的名字一样,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。

缺点:①效率问题:标记和清除两个过程的效率都不太高。②空间问题:标记清除后会产生大量不连续的内存碎片,碎片空间太多可能会导致程序运行过程中需要分配较大的对象时,无法找到足够的连续内存而不得不提前触发垃圾收集动作。

timg?image&quality=80&size=b9999_10000&sec=1525154332717&di=41f97a081ff2091baacebe0654ab92fd&imgtype=jpg&src=http%3A%2F%2Fimg0.imgtn.bdimg.com%2Fit%2Fu%3D3447506915%2C1238041037%26fm%3D214%26gp%3D0.jpg

 

2.复制算法

为了解决效率问题,一种称为“复制”的收集算法出现。

它将可用的内存按容量划分成大小相等的两块,每次只使用其中的一块,当这一块内存用完了,就将还存活着的对象复制到另一块上面,然后再把已使用过的内存空间一次性清理掉。

优点:①不用考虑内存碎片等复杂情况。②实现简单,运行高效。

缺点:只能使用一般的内存,内存牺牲过大。timg?image&quality=80&size=b9999_10000&sec=1525157011085&di=d58bb7dcbc741f7540c20dedf693dcc7&imgtype=0&src=http%3A%2F%2Fimg2.shangxueba.com%2Fimg%2Fkaifa%2F20140904%2F11%2FF9BBBA10A216B368CFB3087F1517084E.png

改进优化:现在的商业虚拟机采用这种收集算法来回收新生代。IBM公司的专门研究表明,新生代中的对象98%是“朝生夕死”的,所以并不需要按照1:1的比例来划分内存空间。而是将内存分为一块较大的Eden空间和两块较小的Survivor空间。每次使用Eden和其中一块Survivor。当回收时,将Eden和Survivor上还存活的对象一次性复制到另一块Survivor上,最后清理掉刚才的Eden和Survivor空间。(HotSpot中比例为8:1:1)

当然98%对象可回收只是一般场景下的数据,我们没有办法保证每次回收都只有不多于10%的对象存活,当Survivor空间不太够用时,我们需要依赖其他内存(这里指老年代)进行分配担保

如果另一块Survivor空间没有足够空间来存放上一次新生代收集下来的存活对象时,这些对象将直接通过分配担保机制进入老年代。

3.标记-整理算法

复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低。更关键的是如果不想浪费50%的空间,就需要额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存活的极端情况。所以在老年代中,一般不能直接选用这种算法。

根据老年代的特点,有人提出了另外一种“标记-整理”算法。标记过程和之前一样,但后续是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。

timg?image&quality=80&size=b9999_10000&sec=1525157071421&di=f62aceed8cd5719d54c03b3c0d282732&imgtype=0&src=http%3A%2F%2Fimage.codes51.com%2FArticle%2Fimage%2F20160321%2F20160321124230_0720.png

 

4.分代收集算法

当前商业虚拟机的垃圾收集都采用“分代收集”算法,这种算法并没有什么新的思想,只是根据对象存活周期的不同将内存划分为几块。一般都是把java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。

在新生代中,每次垃圾收集时都会发现有大批对象死去,只有少量存活,那就选用复制算法;

而老年代因为对象存活率高,没有额外空间对他进行分配担保,就必须使用“标记-清理”或者“标记-整理”算法来进行回收。

转载于:https://my.oschina.net/u/3786691/blog/1805165

你可能感兴趣的文章
Android中SurfaceView的使用详解
查看>>
Websocket
查看>>
linux tar打包
查看>>
Android 通过URL scheme 实现点击浏览器中的URL链接,启动特定的App,并调转页面传递参数...
查看>>
LeetCode: Construct Binary Tree from Preorder and Inorder Traversal 解题报告
查看>>
最近创办了一个java学习邮件列表
查看>>
LightOJ 1285 - Drawing Simple Polygon (几何,极角排序)
查看>>
IronPython 个人网站样例----宝藏挖掘
查看>>
"~/" asp.net 表示路径的方法
查看>>
NoClassDefFoundError:aspectj/weaver/reflect/ReflectionWorld$Reflection
查看>>
sencha 2.3中自己定义PullRefreshFn给PullRefresh加入下拉刷新事件
查看>>
Python 编码风格指南
查看>>
Ubuntu 虚拟机空间不足增加空间笔记
查看>>
UML的类图关系分为: 关联、聚合/组合、依赖、泛化(继承)
查看>>
每篇半小时1天入门MongoDB——3.MongoDB可视化及shell详解
查看>>
读csv文件
查看>>
AndroidStudio3.0到3.1遇到的坑
查看>>
Linux将rm命令设置为回收站【转】
查看>>
2012第50周星期二
查看>>
[AX]AX2012 R2 采购订单的“Request change”
查看>>