写点什么

分布式架构演进 + 相关笔记参考,面试经历分享

发布于: 2021 年 08 月 02 日

GC 概述

垃圾收集(Garbage Collection)通常被称为“GC”,由虚拟机“自动化”完成垃圾回收工作。


思考一个问题,既然 GC 会自动回收,开发人员为什么要学习 GC 和内存分配呢?为了能够配置上面的参数配置?参数配置又是为了什么?


当需要排查各种内存溢出,内存泄露问题时,当垃圾成为系统达到更高并发量的瓶颈时,我们就需要对 GC 的自动回收实施必要的监控和调节。


JVM 中程序计数器、虚拟机栈、本地方法栈 3 个区域随线程而生随线程而灭。栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理。它们的内存分配和回收都具有确定性。


因此,GC 垃圾回收主要集中在堆和方法区,在程序运行期间,这部分内存的分配和使用都是动态的。


下面通过概念和具体的算法来了解 GC 垃圾回收的过程。

如何判断对象存活

判断对象常规有两种方法:引用计数算法和可达性分析算法(Reachability Analysis)。


引用计数算法:给对象添加一个引用计数器,每当有一个地方引用它时计数器加 1,引用释放时计数减 1,当计数器为 0 时可以回收。


引用计数算法实现简单,判断高效,在微软 COM 和 Python 语言等被广泛使用,但在主流的 Java 虚拟机中没有使用该方法,主要是因为无法解决对象相互循环引用的问题。


可达性分析算法:基本思想是通过一系列称为“GC Root”的对象(如系统类加载器、栈中的对象、处于激活状态的线程等)作为起点,基于对象引用关系,开始向下搜索,所走过的路径称为引用链,当一个对象到 GC Root 没有任何引用链相连,证明对象是不可用的。



上图中中绿色部分为存活对象,灰色部分为可回收对象。虽然灰色部分内部依旧有关联,但它们到 GC Root 是不可达的。

面试问题

面试官,说说 Java GC 都用了哪些算法?分别应用在什么地方?


答:复制算法、标记清除、标记整理……


你还在单纯的死记硬背么?继续往下看,你会豁然开朗,再也不用死记硬背了。

标记清除算法

标记清除(Mark-Sweep)算法,包含“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。


标记清除算法是最基础的收集算法,后续的收集算法都是基于该思路并对其缺点进行改进而得到的。



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

复制算法

复制(Copying)算法:将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当一块内存用完了,就将还存活着的对象复制到另外一块上,然后清理掉前一块。



每次对半区内存回收时、内存分配时就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。


缺点:将内存缩小为一半,性价比低,持续复制长生存期的对象则导致效率低下。


JVM 堆中新生代便采用复制算法。回到最初推分配结构图。



在 GC 回收过程中,当 Eden 区满时,还存活的对象会被复制到其中一个 Survivor 区;当回收时,会将 Eden 和使用的 Survivor 区还存活的对象,复制到另外一个 Survivor 区,然后对 Eden 和用过的 Survivor 区进行清理。


如果另外一个 Survivor 区没有足够的内存存储时,则会进入老年代。


这里针对哪些对象会进入老年代有这样的机制:对象每经历一次复制,年龄加 1,达到晋升年龄阈值后,转移到老年代。


在这整个过程中,由于 Eden 中的对象属于像浮萍一样“瞬生瞬灭”的对象,所以并不需要 1:1 的比例来分配内存,而是采用了 8:1:1 的比例来分配。


而针对那些像“水熊虫”一样,历经多次清理依旧存活的对象,则会进入老年代,而老年的清理算法则采用下面要讲到的“标记整理算法”。

总结

就写到这了,也算是给这段时间的面试做一个总结,查漏补缺,祝自己好运吧,也希望正在求职或者打算跳槽的 程序员看到这个文章能有一点点帮助或收获,我就心满意足了。多思考,多问为什么。希望小伙伴们早点收到满意的 offer! 越努力越幸运!


金九银十已经过了,就目前国内的面试模式来讲,在面试前积极的准备面试,复习整个 Java 知识体系将变得非常重要,可以很负责任的说一句,复习准备的是否充分,将直接影响你入职的成功率。但很多小伙伴却苦于没有合适的资料来回顾整个 Java 知识体系,或者有的小伙伴可能都不知道该从哪里开始复习。我偶然得到一份整理的资料,不论是从整个 Java 知识体系,还是从面试的角度来看,都是一份含技术量很高的资料。


感兴趣的朋友可以点击这里获得免费领取!



评论

发布
暂无评论
分布式架构演进+相关笔记参考,面试经历分享