您的位置 首页 java

Java面试必考问题:有哪几种常用的垃圾回收算法

前文《 》介绍了堆内存的管理机制,堆内存是主要的垃圾回收的场所。对于垃圾回收的算法,在平时面试中也是经常考察的问题。 垃圾回收器 (Garbage Collector)在Java 虚拟机 JVM )中也是非常重要的一个组成部分。

Java面试必考问题:有哪几种常用的垃圾回收算法

垃圾回收器在JVM虚拟机的执行引擎中

垃圾回收(Gabage Collection) 不是Java语言的首创,第一代的垃圾回收器是1959年 Lisp 引入的,这项技术迄今为止一直在不断演进。本文主要介绍垃圾回收中用到的一些主要算法。

垃圾回收的前提是能够判断出来什么是垃圾,识别出哪些对象是已经没有用的了,才能够被回收。

垃圾判断算法

引用 计数法

引用计数法是给每个对象都添加一个引用 计数器 。每当有引用某个对象的时候,这个对象的引用计数器的值就加1;当这个引用失效后,计数器的值随之减1。

若某个对象的计数器的值为0,那么就表示这个对象没有被其他对象引用,不再被需要的时候就可以被当作垃圾回收了。

Java面试必考问题:有哪几种常用的垃圾回收算法

对象间的循环引用

引用计数法的缺点也很明显,就是无法解决对象之间循环引用的问题。假设有两个对象 A 和 B 之间互相引用,也就是说 A 对象中的一个成员引用了 B,B 中的一个成员引用了 A,这种情况下,两个对象的引用计数器永远不可能是0,无法被GC回收。

可达性分析算法

可达性分析算法也称为根搜索算法。通过一系列GC Roots对象作为起点,往下搜索,搜索过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,证明该对象是不存活的,应该要被回收。

Object5、6、7不在GC Roots的引用链上,因此不是存活对象

通过可达性算法,成功解决了引用计数所无法解决的循环依赖问题,只要无法与 GC Roots 建立直接或间接的连接,系统就会判定为可回收对象。

虚拟机栈、方法区和本地方法栈引用的对象都可作为GC ROOT对象

Java内存区域中可以作为GC Roots的对象包括:

  • 虚拟机栈中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中引用的对象

对于Java内存区域的划分,可以参见前文《 》。

垃圾回收算法

常用的垃圾回收算法主要有以下几种。

标记清除法

堆内存中:红色代表非垃圾,黑色代表垃圾,直接把黑色的垃圾部分扣掉就是标记清除法。

标记清除法

只使用单一的标记清除法,问题是内存空间会变得很零碎,如果有大的对象,可能就分配不出来内存。

标记整理法:

与标记清除法类似。区别在于标记整理法不仅对不存活的对象进行清除,还对存活的对象进行重新整理,因此不会产生内存碎片化的现象。

标记整理法

标记整理算法对内存变动更频繁,需要整理所有存活对象的引用地址,效率上比较差。

复制算法:

复制算法也是在标记清除算法的基础上演化而来。它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。

复制算法

当一块的内存用完了,就将还存活着的对象复制到另外一块内存上,再把已使用过的内存空间一次性清理掉。在复制的同时,把存活对象进行整理,消除了内存碎片。

HotSpot的GC机制

实际的JVM有多个垃圾回收器,回收机制以复制算法为主,同时也会针对不同代的内存回收特点,综合使用多种回收算法。

HotSpot虚拟机的7种垃圾回收器,分别用于不同代的内存区域

HotSpot虚拟机采用分代收集算法,把堆内存分为新生代和老年代。新生代分为Eden区和Survivor区,Survivor区再一分为二,一个使用,另一个空置留作备用。

HotSpot虚拟机堆内存

当Eden区满了,就把有用对象复制到其中一个Survivor区,清空Eden区;当两区都满了,就把有用对象复制到另外一个空置的Survivor区,并把两区都清空,被被清空的Survivor区留作备用。对于非常大的对象,Survivor区装不下,就直接放入老年代。

对于HotSpot堆内存的管理机制可以参考前文《 》。

我会持续更新关于物联网、云原生以及数字科技方面的文章,用简单的语言描述复杂的技术,也会偶尔发表一下对IT产业的看法, 欢迎大家关注 ,谢谢。

文章来源:智云一二三科技

文章标题:Java面试必考问题:有哪几种常用的垃圾回收算法

文章地址:https://www.zhihuclub.com/181036.shtml

关于作者: 智云科技

热门文章

网站地图