垃圾收集器和循环引用 [英] Garbage collector and circular reference

查看:140
本文介绍了垃圾收集器和循环引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这两个类:

  public class A 
{
B b;
public A(B b){this.b = b; }
}

公共类B
{
A a;
public B(){this.a = new A(this); }



$ b

如果我有类似上面的类,那么这些类的对象是垃圾收集器(GC)收集?

假设我这样做:

  void f()
{
B b = new B();



$ b

在这种方法中,我创建了一个 B的实例称为 b ,并且当方法返回时, b 超出范围,并且GC应该能够收集它,但是如果要收集它,它必须首先收集 a ,它是 B ,并且收集 a ,它需要收集 b first,它是 A 。它变成了圆形。所以我的问题是:这样的循环引用是否会阻止GC收集对象?




  • 如果是的话,我们如何避免这个问题?我们如何确保我们的课堂设计没有循环参考?是否有帮助我们检测循环引用的工具(或编译器选项)?

  • 如果不是,我们在哪里以及为什么使用 WeakReference class?它的目的是什么?


解决方案

.Net垃圾回收器可以绝对处理循环引用。 非常高级别垃圾收集器的工作原理是......




  • 从本地,静态和GC固定对象。通过遍历这些对象的子元素,标记每个可以到达的对象

  • 收集每个未标记的对象。



这样可以很好地收集循环引用。只要它们中的任何一个都不可从已知不可收集的对象中获得,那么循环引用基本上是不相关的。



注意:我意识到我遗漏了很多有趣的细节,以便让答案简单直接。


Consider these two classes:

public class A
{
     B b;
     public A(B b) { this.b = b; }
}

public class B
{
     A a;
     public B() { this.a =  new A(this); }
}

If I have classes designed like above, would the objects of such classes be collected by Garbage Collector (GC)?

Suppose I do this:

void f()
{
     B b = new B();
}

In this method, I create an instance of B called b, and when the method returns, b goes out of scope, and the GC should be able to collect it, but if it were to collect it, it would have to collect a first which is the member of B, and to collect a, it needs to collect b first which is the member of A. It becomes circular. So my question is : is such circular reference going to prevent GC from collecting the objects?

  • If yes, then how can we avoid this problem? How can we make sure that we don't have circular reference in our class design? Is there any tool (or compiler option) that helps us detecting circular reference?
  • If no, where and why do we use WeakReference class? What is its purpose?

解决方案

The .Net garbage collector can absolutely handle circular references. The very high level view of how the garbage collector works is ...

  • Start with locals, statics and GC pinned objects. None of these can be collected
  • Mark every object which can be reached by traversing the children of these objects
  • Collect every object which is not marked.

This allows for circular references to be collected just fine. So long as none of them are reachable from an object known to be uncollectable then the circular reference is essentially irrelevant.

Note: I realize I've left out many fun details in order to keep this answer simple and direct

这篇关于垃圾收集器和循环引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆