垃圾回收算法(1)-引用计数法


算法原理

引用记数法在GC执行垃圾回收之前,首先需要区分出内存中哪些是存活的对象,哪些是已经死亡的对象,只有被标记为已经死亡的对象,GC才会在执行垃圾回收时,释放掉其所占用的内存空间。

比如说,当我们编写以下代码时

String p = new String("abc")

abc这个字符串对象的引用计数值为1.

而当我们去除abc字符串对象的引用时,则abc字符串对象的引用计数减1

p = null

由此可见,当对象的引用计数为0时,垃圾回收就发生了。

引用计数算法很简单,它实际上是通过在对象头中分配一个空间来保存该对象被引用的次数。如果该对象被其它对象引用,则它的引用计数加一,
如果删除对该对象的引用,那么它的引用计数就减一,当该对象的引用计数为0时,那么该对象就会被回收。

严重问题

引用记数法有一个严重的问题,即无法处理循环引用的情况。一个简单的循环引用问题的描述如下:有对象A和对象B,对象A中含有对象B的引用,对象B中含有
对象A的引用。此时,对象A和对象B的引用计数器都不为0,但是在系统中却不存在任何第3个对象引用了A或B。也就是说,A和B是应该被回收的垃圾对象,但是由于
垃圾对象之间相互引用,从而使垃圾回收器无法识别,引起内存泄漏。

将最后一个元素的next属性指向第一个元素,即引用第一个元素,从而构成循环引用。这个时候如果将列表的头head赋值为null,此时列表的各个元素的计数器都不为0,同时也失去了对列表的引用
控制,从而导致列表元素不能被回收。

引用计数器拥有一些特性,首先它需要单独的字段存储计数器,这样的做法增加了存储空间的开销。其次,每次赋值都需要更新计数器,这增加了时间开销。再者,垃圾对象便于辨识,只要计数器为0,就可作为垃圾回收
,接下来它能方便及时的回收垃圾,没有延迟性最后不能解决循环引用的问题,正是由于最后一条知名缺陷,导致在java的垃圾回收器中没有使用这类算法。


文章作者: 少年闰土
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 少年闰土 !
评论
 上一篇
垃圾回收算法(2)-根搜索算法 垃圾回收算法(2)-根搜索算法
前言相对于引用计数算法而言,根搜索算法不仅同样具备实现简单和执行高效等特点,更重要的是该算法可以有效的解决在引用记数法中一些已经死亡的对象因为相互引用而导致的无法正确被标记的问题,防止内存泄漏的发生。 算法原理根搜索算法是以根对象集合为起始
2020-07-07
下一篇 
面向对象的7种设计原则(7)-开闭原则 面向对象的7种设计原则(7)-开闭原则
开闭原则开闭原则是面向对象世界里最基础的设计原则,它指导我们如何建立一个稳定,灵活,可扩展的系统。开闭原则定义如下: Software entities like classes,modules and functions should
2020-07-06
  目录