文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

浅谈Java垃圾回收机制

2024-04-02 19:55

关注

一.什么是垃圾

java中,什么样的对象是垃圾?有人说:没有被引用的对象就是垃圾对象.我一开始对此也是深信不疑的,但是当年我这么回答面试官的时候,得到的是一个大大的白眼.

判断一个对象是否是垃圾,有两种算法,一种是引用计数法,但是,这种方法解决不了循环引用的问题.



public class Demo{
    public Demo instance;
    public static void main(String[] args) {
        Demo a=new Demo();
        Demo b=new Demo();
        a.instance=b;
        b.instance=a;
        a=null;
        b=null;
    }
}

这里写图片描述

另外一种方法,可以解决这种循环引用问题,那就是可达算法.关于可达算法,就我目前所知道的,有两种解释:

大众说法:
通过一系列的称谓“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所有走过的路径为引用链,当一个对象到GC Roots没有任何引用链项链时,则证明此对象时不可用的.

这里写图片描述 

某位前辈的理解:
选取一个对象作为GC Roots,调用其它对象去指向这个GC Roots,如果这些对象最终到达GC Roots,那表明所选取的对象不是垃圾.反之,如果对象到不了GC Roots,那么所选取的对象就是垃圾对象,就可以进行垃圾回收了.(这是一种说法);
对象指向GC Roots所形成的链条叫GC链.

这里写图片描述 

至于这两种方法谁对谁错,这就要看个人的水平了.
不管怎么样,垃圾反正是产生了,那么接下来就是该怎么回收垃圾了.

二.怎么回收垃圾

2.1 静态对象什么时候变成垃圾被回收

在说垃圾回收前,先说一个题外话,我上面所说的垃圾对象,其实是指一般的对象,因为静态对象有些不同.
我经常听人说:静态方法随着类的加载而加载,随着类的消失而消失.但是,现在在我看来,这种说法是有问题的.
因为,静态对象要成为垃圾被回收,要满足三个条件:

1. 这个类的对象变成了垃圾
2. 加载这个类的类加载器变成了垃圾
3. 关于这个对象的class对象也变成了垃圾
只有满足这三个条件,静态对象才会变成垃圾被回收,要不然静态对象会一直存在于永久带中.

2.2 新生代和年老代

既然要说垃圾回收,那么我们就先来看看跟垃圾回收密切相关的堆内存(新生代和年老代)

这里写图片描述
这里写图片描述 

如图所示:
堆内存按1:2被划分成了年轻代(新生代)和年老代.新生代又被按照8:1:1的比例分为一个eden区和两个survivor(survivor0,survivor1)区
关于分区,我只讲到这里,有兴趣的可以自己研究.

三、垃圾回收算法

3.1 标记清除算法

这里写图片描述
这里写图片描述
这里写图片描述 

如图所示:标记清除算法分成两步,第一步,标记要回收的垃圾对象,第二步就是清除被标记的垃圾对象.
同样,如图所示,标记清除算法会产生大量的内存碎片,而且效率低.所以,为了解决这个问题,出现了复制清除算法.

3.2 复制清除算法(专门用于处理年轻代垃圾的)

这里写图片描述
这里写图片描述
这里写图片描述 

如图所示,所谓复制清除算法,就是在要进行垃圾回收的时候,先将活着的对象整齐的复制到一块空闲区域,然后再将原来的区域的垃圾全部清除.

复制清除算法的优点:效率高于标记清除算法,活着的对象是整齐排列的,没有内存碎片.

但是这个方法的缺点也很明显,那就是浪费空间.,毕竟如果按照1:1比例来划分空间的话,那么将会有50%的空间被浪费.不过,在jvm中,年轻代空间并不是按照1:1来划分的,而是按照8:1:1的比例分为一个eden区和两个survivor(survivor0,survivor1)区。一个Eden区,两个 Survivor区(一般而言)。大部分对象在Eden区中生成。回收时先将eden区存活对象复制到一个survivor0区,然后清空eden区,当这个survivor0区也存放满了时,则将eden区和survivor0区存活对象复制到另一个survivor1区,然后清空eden和这个survivor0区,此时survivor0区是空的,然后将survivor0区和survivor1区交换,即保持survivor1区为空,这样的过程也被叫做Minor GC,每进行Minor GC一次,存活着的对象的年龄就会加1,当存活着的对象的年龄到达15岁时,就会被送进年老代.
当然,当整个当survivor1区不足以存放 eden和survivor0的存活对象时,也会将存活对象直接存放到年老代。若是年老代也满了就会触发一次Full GC,也就是新生代、老年代都进行回收

3.3 标记清理算法(年老代)

这里写图片描述 

将活着的对象一个接一个的按顺序排好,然后再清除变成垃圾的对象.这种方法不会造成碎片,也不会造成内存的浪费.但是效率不高.所以,这种方法不适合在年轻代使用,而是在对象生命力很顽强的年老代使用

3.4 分类算法

所谓分类算法,就是根据内存的不同,采用不同的垃圾回收方式(上面的1,2,3)进行垃圾回收.

暂时就先说到这里,因为再说下去,还会有什么GC停顿以及垃圾收集器等.如果大家想要了解更多的垃圾回收的知识,可以看类似<<深入理解Java虚拟机:JVM高级特性与最佳实践>>等书籍.毕竟这些书是我的一位前辈推荐给我的.

这里写图片描述

到此这篇关于浅谈Java垃圾回收机制的文章就介绍到这了,更多相关Java垃圾回收内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯