我是靠谱客的博主 成就钻石,最近开发中收集的这篇文章主要介绍GC是如何进行对象回收的?,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1、垃圾回收器是所有对象都回收吗?



    垃圾回收器回收对象前都会验证哪些对象“活着”哪些对象已经“死去”,发现“死去”的对象就会进行垃圾回收。通常有两种算法验证对象存活:引用计数器和根可达分析算法。但在java中使用后者。
    根可达分析算法是指找到GC Roots根节点并逐一向下寻找对象引用,如果某个对象不存在引用链则该对象到GC Roots不可达,证明此对象将不再使用。

在这里插入图片描述
如图所示5,6,7对象因为没有可达GC Roots的引用链所以不再使用,而1,2,3,4对象则反之。
    那么在java中有哪些对象是固定使用根可达分析算法呢?
在这里插入图片描述
2、GC垃圾回收算法

2.1、标记-清除算法
定义:标记出所有清除的对象标记完成后再清除。
缺点:不稳定、内存空间碎片化问题

在这里插入图片描述
不稳定:堆中包含大量对象,而且回收对象多,这时会进行大量的标记和清除工作,导致标记和清除过程的执行效率变低,所以执行不稳定。
内存空间碎片化:标记清除工作之后会产生大量且不连续的空间碎片,空间碎片过多会导致程序在运行中需要分配大对象时无法找到足够连续的内存空间,从而提前触发了GC工作。

2.2、标记-复制算法
定义:将内存分为大小相等的两块,拿出其中一块存储对象当这块内存用完了就将存活对象复制到另一块内存中,再一次清除原来使用的那一块内存。
缺点:如果内存中多数都是存活对象,那么复制必定产生大量的内存开销,浪费内存空间。

在这里插入图片描述
2.3、标记-整理算法
定义:前面和标记-清除算法一样,但是不直接对可回收对象进行清理,而是所有存活的对象都向内存空间一段移动并按内存地址排列,然后直接清理边界以外的对象。
在这里插入图片描述
    这样处理虽然不浪费内存空间,也不用担心空间碎片化问题,但如果存活对象过多且更新所有对象引用这样也是很重的操作,会导致正在运行的程序暂停。另一方面如果不移动存活对象则会产生大量的空间碎片。

3、总结



    文中所述的垃圾回收算法各有千秋,都是基于GC Roots可达性分析算法来判定存活对象,当GC线程启动时会暂停所有正在运行的程序,从效率上来说标记-清理算法优于标记-整理算法,标记整理算法又优于标记-复制算法;从空间利用上来说,标记-整理算法高于标记-清除算法,标记清除算法高于标记-复算法。

参考:《深入理解java虚拟机》

最后

以上就是成就钻石为你收集整理的GC是如何进行对象回收的?的全部内容,希望文章能够帮你解决GC是如何进行对象回收的?所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部