前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【编程语言】Java虚拟机垃圾回收算法,2020年的面试你准备好了吗

【编程语言】Java虚拟机垃圾回收算法,2020年的面试你准备好了吗

作者头像
kk大数据
发布2020-02-14 16:54:31
3780
发布2020-02-14 16:54:31
举报
文章被收录于专栏:kk大数据kk大数据

熟悉 Java 的朋友一定知道 Java 虚拟机了,熟练掌握 Java 虚拟机是一个高级工程师的基础素养哦,当然面试官在问到 Java 虚拟机的时候,一定会问到 垃圾回收算法的。

2020年的金三银四很快就要来了,不知道朋友们有没有在夜深人静的时候,放下手机里的小姐姐,仔细捋一捋垃圾回收算法呢?没有也没关系哦,今天我们就来一起捋一下。

1

技术背景需要先了解一下

按道理,装逼的正确姿势需要从什么是 Java,Java 的发展史,Java 虚拟机说起的,但我们今天不装逼,假设各位聪明的小伙伴都知道了,我们直奔主题

2

哪些内存需要回收

大家都知道,虚拟机的内存结构包括以下五个区域:方法区、堆、虚拟机栈、本地方法栈、程序计数器。其中,虚拟机栈、本地方法栈、程序计数器是线程私有的区域,随线程生而生,随线程灭而灭,所以不存在垃圾回收的说法。我们重点需要关注的是堆和方法区两个区域。

在回收之前,需要知道哪些对象可以回收,哪些对象不可以被回收。这就需要知道哪些对象不可回收的算法。

1、引用计数算法

引用计数算法是垃圾回收的早期策略,也是一个非常简单和高效的策略。主要原理是:给对象添加一个引用计数器,每当有一个地方引用到这个对象时,就给对应的计数器加1;当引用失效,超过了生命周期或者设置为一个新值时,就给计数器减1. 任何计数器为0的对象,就是垃圾收集的对象了。

但是有一个缺点是,它很难解决对象之间的循环引用问题。

比如,对象1的一个属性引用了对象2,对象2的一个属性引用了对象1,当把对象1和对象2都设置为 null 时,堆中它们的属性仍然引用着对方,导致永远都不可能被回收了。

2、可达性分析算法

主流的商用编程语言,如 Java,C#,古老的 Lisp,的实现都是用可达性分析算法来判定对象是否存活的。它的理论基础是离散数学的图论,即把所有的引用关系看成是一张图,通过一系列的称为 “GC Roots” 的对象作为起点,从这些节点开始向下搜索,直到遍历完所有对象,最终那些没有被遍历到的对象就可以被判定位可回收的对象。

如上图,ObjD 和 Obj E,就是可以回收的对象

常用的垃圾回收算法

说了半天,终于到主角登场了。

1、标记-清除算法

顾名思义,算法分为 “标记” 和 “清除” 两个阶段。

标记阶段,根据上文提到的垃圾判定的算法来标记哪些对象时垃圾;

清除阶段,标记完成后,统一回收所有被标记对象。

它是最基础的算法,因为后续的算法都是基于这种思路,并且对其不足的地方改进后得到的。

它有两个缺点,一是效率不高,标记和清除两个阶段的效率都不高;二是空间问题,标记清除之后,会产生大量的不连续的内存碎片。

2、复制算法

复制算法的提出是为了克服效率和碎片过多的问题。它的基本思想是:将内存分为大小相同的两块,每次只使用其中的一块。当其中一块的对象满了,就用标记算法,将还存活的对象移动到另外一块上,然后一次性回收掉这一块对象。

因为每次都是对一整块内容进行回收,也就不用考虑内存碎片等复杂的情况,只要移动栈顶的指针,按顺序分配内存即可。

现代的商业虚拟机都是采用这种算法来回收新生代。但是不是 1:1 分配的,而是将内存分为一块较大的 Eden 区和两块较小的 Survivor 区。每次只使用 Eden 和 其中一块 Survivor 区。每次回收时,把 Eden 和 一块 Survivor 区还存活的对象一次性复制到 另一块 Survivor 区来,最后清理掉 Eden 和 其中一块 Survivor 区。

3、标记整理算法

标记 - 整理算法 采用 和 标记 - 清除算法一样的方式进行对象的标记,但在清除时不同,不是直接清除,而是把所有的对象都向一端移动,然后直接清理掉端边界以外的内存

4、分代收集算法

当代虚拟机的垃圾都是采用了 “分代收集” 算法,它并没有新的思想,而是根据对象声明周期不同,将内存 划分为若干个不同的区域,一般讲内存划分为“新生代”和“老年代”,在堆之外,还有一个“永久代”。

在 “新生代” 中,每次都有大量的垃圾需要回收,那就选用复制算法;而在 “老年代” 中,对象的存活率高,就必须使用 “标记 - 清理” 或者 “标记 - 整理” 的算法来进行回收。

好了,到这里为止,垃圾回收的相关算法思想都讲完了,但是还是远远不够的,因为不同的垃圾收集器,使用了不同的垃圾回收算法,回收的策略也会不一样,后续还会继续更新。

敬请持续关注 【程序员凯】 公众号。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 KK架构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档