`

垃圾回收器如何处理循环引用

    博客分类:
  • Java
 
阅读更多

垃圾回收是一门编程语言中必不可少的一部分,不论是手动释放内存的C和C++,还是自动回收垃圾的Java和C#等语言。对于Java这样的语言,一般的开发者不强求关心对象回收和内存释放,但是理解垃圾回收对开发工作还是大有裨益的。

在编程语言中,普遍存在着循环引用这样的问题,垃圾回收器是如何处理循环引用呢,常用的垃圾回收有引用计数和引用对象遍历两种实现,它们各自又是如何处理循环引用呢?本文讲以JVM中的GC为例逐一回答这些问题。

何为循环引用

如果有两个或者以上的对象,它们彼此引用,就会造成循环引用。如下面的例子

1
2
3
4
5
6
7
8
class Node {
  Node next;
}
Node a = new Node();
Node b = new Node();
a.next = b;
b.next = a;

代码中,a对象引用了b对象,b对象也引用了a对象,这种情况下a对象和b对象就形成了循环引用。

引用计数GC处理

什么是引用计数

引用计数是一种垃圾回收的形式,每一个对象都会有一个计数来记录有多少指向它的引用。其引用计数会变换如下面的场景

  • 当对象增加一个引用,比如赋值给变量,属性或者传入一个方法,引用计数执行加1运算。
  • 当对象减少一个引用,比如变量离开作用域,属性被赋值为另一个对象引用,属性所在的对象被回收或者之前传入参数的方法返回,引用计数执行减1操作。
  • 当引用计数变为0,代表该对象不被引用,可以标记成垃圾进行回收。

如何处理

实际上单纯的基于引用计数实现的计数器无法处理循环引用带来的问题。

CPython的垃圾回收就是采用引用计数,采用引用计数的主垃圾回收器会清理垃圾,对于那些因为循环引用无法清理的对象,CPython会不时启动一个辅助的基于引用遍历的垃圾回收器来清理它们。

引用遍历GC处理

什么是引用对象遍历

垃圾回收器从被称为GC Roots的点开始遍历遍历对象,凡是可以达到的点都会标记为存活,堆中不可到达的对象都会标记成垃圾,然后被清理掉。 GC Roots有哪些

  • 类,由系统类加载器加载的类。这些类从不会被卸载,它们可以通过静态属性的方式持有对象的引用。注意,一般情况下由自定义的类加载器加载的类不能成为GC Roots
  • 线程,存活的线程
  • Java方法中的局部变量或者参数
  • JNI方法栈中的局部变量或者参数
  • JNI全局引用
  • 用做同步监控的对象
  • 被JVM持有的对象,这些对象由于特殊的目的不被GC回收。这些对象可能是系统的类加载器,一些重要的异常处理类,一些为处理异常预留的对象,以及一些正在执行类加载的自定义的类加载器。但是具体有哪些前面提到的对象依赖于具体的JVM实现。

如何处理

基于引用对象遍历的垃圾回收器可以处理循环引用,只要是涉及到的对象不能从GC Roots强引用可到达,垃圾回收器都会进行清理来释放内存。

总结

基于引用计数的垃圾回收器无法处理循环引用导致的内存泄露问题,但是其在主流的JVM中很少,几乎所有的JVM都是采用引用对象遍历的方法,垃圾回收器都会处理循环引用潜在的问题。

一本书

分享到:
评论

相关推荐

    谈谈你对垃圾回收机制的了解?.docx

    引用计数算法:就是为对象添加一个引用计数,用于计数对象被引用的情况,如果计数为0,表示 对象可以被回收.(java并没有选择引用计数,因为存在一个基本难题,就是很难处理循环引用关系) 可达性分析:这种类型的垃圾收集...

    【JavaScript源代码】详解JavaScript的垃圾回收机制.docx

     目录 为什么需要垃圾回收(GC)什么是垃圾回收垃圾产生垃圾回收策略引用计数标记循环引用引发的问题解决方法引用计数算法的优缺点标记清除算法核心思想标记清除算法优缺点标记整理算法V8引擎的垃圾回收回收新生代...

    flex垃圾回收机制是什么原理

    而在这棵树之外的孤岛对象或者由于循环引用形成的孤岛对象集合被标记为“无效”,垃圾收集器会在合适的时间销毁这些无效对象,完成一次垃圾收集。而垃圾收集器是运行在虚拟机中的一个低优先级的守护进程,为了不影响...

    Python的垃圾回收机制

    python垃圾回收机制 python中有自动内存回收机制,一般情况不需要程序员来处理。 方式1:引用计数 若此对象无其他对象引用,则立马回收掉 优点:简单、实时(将处理垃圾时间分摊到运行代码时,而不是等到一次回收) ...

    Python垃圾回收机制

    Garbage collection(GC垃圾回收) python采用的是引用计数机制为主,标记-清除和分代收集(隔代回收、分代回收)两种机制为辅的策略 引用计数机制的优点: 1、简单 2、实时性:一旦没有引用,内存就直接释放了。不用像...

    深入理解Python内存管理与垃圾回收,再也不怕问了(二)

    如果一个对象的引用计数为0,Python解释器就会回收这个对象的内存,但引用计数的缺点是不能解决循环引用的问题,所以我们需要标记清除和分代回收。 什么是引用计数 每个对象都有存有指向该对象的引用总数 查看某个...

    如何解决Java的循环引用问题

    在Java开发中,循环引用是指两个或多个对象相互引用,导致无法被垃圾回收器回收,从而引发内存泄漏的问题。这种问题在大型应用程序中经常会出现,因此解决循环引用问题是非常重要的。 例子及解决方法看附件

    Python垃圾回收机制三种实现方法

    引用计数 Python语言默认采用的垃圾收集机制是『引用计数法 Reference Counting』,该...缺点:它的缺点是需要额外的空间维护引用计数,这个问题是其次的,不过最主要的问题是它不能解决对象的“循环引用”,因此,

    理解Python垃圾回收机制

    引用计数的缺陷是循环引用的问题。 在Python中,如果一个对象的引用数为0,Python虚拟机就会回收这个对象的内存。 #encoding=utf-8 __author__ = 'kevinlu1010@qq.com' class ClassA(): def __init__(self): ...

    Python的垃圾回收机制深入分析

    在引用计数的基础上,还可以通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用的问题。通过“分代回收”(generation collection)以空间换取时间来进一步提高垃圾回收的效率。 二、引用计数 在...

    浅谈Python的垃圾回收机制

    引用计数的缺陷是循环引用的问题。 在Python中,如果一个对象的引用数为0,Python虚拟机就会回收这个对象的内存。 #encoding=utf-8 __author__ = 'kevinlu1010@qq.com' class ClassA(): def __init__(self): ...

    Python小白垃圾回收机制入门

    Python默认的垃圾收集机制是“引用计数”,每个对象维护了一个ob_ref字段。它的优点是机制简单,当新的引用指向该对象时,引用计数加1,当一个对象的引用被销毁时减1,一旦对象的引用计数为0,该对象立即被回收,所...

    垃圾回收机制

    垃圾回收机制 判断对象是否存活的方法 引用计数法 每个对象上都有一个引用计数,对象每被引用一次,引用计数器就+1,对象引用被释放,引用计数器-1,直到对象的引用计数为0,对象就标识可以回收。但是这个算法有明显...

    python笔记题带答案.doc

    二、垃圾回收 1,当一个对象的引用计数归零时,它将被垃圾收集机制处理掉。 2,当两个对象a和b相互引用时,del语句可以减少a和b的引用计数,并销毁用于引用底 层对象的名称。然而由于每个对象都包含一个对其他对象...

    论文研究-基于关键引用验证的分布式实时垃圾搜集器.pdf

    提出了一种新的分布式垃圾搜集器(GC)机制,即基于关键引用验证的分布式GC。性能分析说明,与以往的分布式GC相比,该算法能以最短的时间延迟回收循环垃圾。尽管该算法为保留引用列表和验证过程需要额外的一些存储...

    python内存管理机制原理详解

    python内存管理机制: 引用计数 垃圾回收 ...当python某个对象的引用计数降为 0 时, 说明没有任何引用指向该对象, 该对象就成为要被回收的垃圾了.(如果出现循环引用的话, 引用计数机制就不再起作用了

    go语言开发技巧入门教程总结.docx

    垃圾回收机制 问题描述:Go的垃圾回收(GC)可能导致程序执行期间的短暂停顿。 解决方案:优化GC配置,减少不必要的对象分配,适时手动释放资源,监控和调整GC策略。 内存泄漏 问题描述:即使有GC,但如果长时间持有...

    Android中的内存泄漏

    引用计数法(有循环引用的问题):Python、Object-C、Swift 用一个计数器记录一个对象被引用的次数,如果引用的次数被减少到0,说明这个对象是垃圾对象 可达性分析法:Java JVM通过一些GC Roots向下搜索,如果可以被GC...

    Python内存管理方式和垃圾回收算法解析

    在列表,元组,实例,类,字典和函数中存在循环引用问题。有 __del__ 方法的实例会以健全的方式被处理。给新类型添加GC支持是很容易的。支持GC的Python与常规的Python是二进制兼容的。 分代式回收能运行工作(目前是...

    java最新面试题50道精讲

    10、解释一下Java中的垃圾回收机制是什么,以及如何配置垃圾回收器? 11、解释Java中的基本语法,包括变量、数据类型、控制结构等。 12、解释Java中的数组是什么,以及如何使用数组? 13、解释Java中的字符串是什么...

Global site tag (gtag.js) - Google Analytics