关于java:GC垃圾回收的原理和涉及的几种算法

4次阅读

共计 1111 个字符,预计需要花费 3 分钟才能阅读完成。

1 GC 垃圾回收的原理

其实垃圾回收的原理很简略:就是判断出死亡的对象,而后革除死亡的,留下存活的即可。那么怎么判断对象曾经死亡呢?常有的有以下两种:

1)援用计数法(Reference Counting):在对象中增加一个援用计数器,每当一个中央援用它时,计数器就加 1;当援用生效时,计数器就减 1; 当援用计数为 0 时就会被回收 。然而它存在一个很大的问题就是循环援用:如下图,当实例化 A 时,A 会持有实例 B,B 会持有 C,C 持有 A。这样一来咱们就会发现: 如果须要回收 A,除了开释初始实例化援用,还须要开释 C 的援用。然而因为 ABC 相互援用,所以就造成谁也无奈开释。支流的垃圾回收都没有采纳这种判断办法,因为须要额定的工作来解决它(感兴趣的童鞋能够看看智能指针)。

2)可达性剖析算法(Reachability Analysis):在 JAVA 虚拟机中就是通过可达性分析法来断定对象是否存活的。思路是通过“GC Roots”的对象(能够认为是确定固定存在的对象)作为起始点,而后从这些节点开始遍历所有援用链,如果某个对象没有 GC Roots 间接或间接的连贯的话,这个对象(红色节点)就被认为程序中不再应用能够被回收了。如下图:

2 垃圾回收的几种算法

标记革除: 其分为“标记”和“革除”两个阶段。首先标记出所有死亡的对象,而后把所有死亡的的对象进行革除操作。如下图,咱们能够分明的看到,这种回收算法有一个很大的问题:造成很多的不间断内存碎片,这样一来,如果须要创立略微大一点的对象,就很可能无奈找到足够大的内存空间。这就须要整个再进行一次标记整顿来解决这一问题(耗时耗力)。

标记整顿: 算法分为”标记 - 整顿 - 革除“阶段,首先须要先标记出存活的对象,而后把他们整顿到一边,最初把存活边界外的内存空间都革除一遍。这个算法的益处就是不会产生内存碎片,然而因为整顿阶段挪动了对象,所以须要更新对象的援用。

标记复制: 算法分标记 - 复制两个阶段。首先会标记存活的对象,实现后,该算法会把存活的对象都复制到一块新的空内存里去。最初将原来的内存空间清空。过程如下图,这个算法最大的问题就是须要很大的内存(理论用的,用于复制的内存空间),同时如果存活的对象十分多的话,标记和复制阶段都就会很慢。同时也波及到了对象地位扭转须要更新援用。只管看起来问题很大,然而依据分代实践:弱分代假说里大多数对象生命周期短,这种状况下标记复制就很适宜了(复制的存活对象少)。至于内存耗费太大的问题,java 虚拟机通过将新生代分为一个 Eden 区与 2 个 Survivo 区,其中一个 Survivo 区用来复制,这样一来极大得进步了内存空间利用率。

本文由博客群发一文多发等经营工具平台 OpenWrite 公布

正文完
 0