简体   繁体   English

C# 垃圾收集与 object 参考

[英]C# garbage collection with object references

In C#, when I have two object obj1 , obj2 composed of a List<string> and I assign both of those objects to the same List<string> object.在 C# 中,当我有两个 object obj1时, obj2List<string>组成,我将这两个对象分配给同一个List<string> object。

If my reference to obj1 goes out of scope but my reference to obj2 does not, is obj1 still eligible for garbage collection, or are there some dependency issues because there is still a reference to the List<string> object?如果我对 obj1 的引用超出了 scope 但我对 obj2 的引用没有,那么 obj1 是否仍有资格进行垃圾收集,或者是否存在一些依赖问题,因为仍然存在对List<string> object 的引用?

In your case, obj1 must be eligible for garbage collection.在您的情况下, obj1必须有资格进行垃圾收集。

You need to look at Jon Skeet's answer here.您需要在这里查看Jon Skeet's answer It clearly explains how garbage collection works on object references.它清楚地解释了垃圾收集如何在 object 引用上工作。

A nice tutorial for you on Object's Lifetime in C# . Object's Lifetime in C#

obj1 should be eligible for garbage collection as long as there are no references to obj1 itself.只要没有对 obj1 本身的引用,obj1 就应该有资格进行垃圾回收。

If my reference to obj1 goes out of scope, but my reference to obj2 does not, is obj1 still eligible for garbage collection, or is there some dependency issues because there is still a reference to the List object?如果我对 obj1 的引用超出了 scope,但我对 obj2 的引用没有,那么 obj1 是否仍有资格进行垃圾收集,或者是否存在一些依赖问题,因为仍然存在对列表 object 的引用?

If I understand you correctly you mean both obj1 and obj2 are of type List<string> and both point to the same List<string> instance.如果我理解正确,您的意思是obj1obj2都是List<string>类型,并且都指向同一个List<string>实例。

When obj1 goes out of scope, there still will be still obj2 as an active reference to the List<string> instance, so the list cannot be garbage collected.obj1离开 scope 时,仍然会有obj2作为对List<string>实例的活动引用,因此无法对列表进行垃圾回收。

If obj1 was part of a reference type on the heap (ie one of its properties) the memory space it occupied may be garbage collected as part of the outer object.如果 obj1 是堆上引用类型的一部分(即其属性之一),则它占用的 memory 空间可能会作为外部 object 的一部分被垃圾收集。 If it was just a reference on the stack, GC will not be involved since the stack will be just unwound at the end of the method call when obj1 falls out of scope.如果它只是堆栈上的引用,则不会涉及 GC,因为当 obj1 掉出 scope 时,堆栈将在方法调用结束时展开。

Keep in mind that obj1 is just a reference (in a way a pointer) to an object on the heap - this object may be garbage collected only when no reference is pointing to it anymore.请记住,obj1 只是对堆上 object 的引用(在某种程度上是指针) - 只有当没有引用指向它时,才会对这个 object 进行垃圾收集。

There are three uses of memory defined in this question:这个问题中定义了 memory 的三种用途:

  • a pointer to the List<string> instance called obj1 .指向名为obj1List<string>实例的指针。
  • a pointer to the List<string> instance called obj2 .指向名为obj2List<string>实例的指针。
  • The instance of List<string> . List<string>的实例。

if obj1 goes out of scope, but obj2 does not, then only the following remain after garbage collection:如果obj1超出 scope,但obj2没有,那么垃圾回收后只剩下以下内容:

  • a pointer to the List<string> instance called obj2 .指向名为obj2List<string>实例的指针。
  • The instance of List<string> . List<string>的实例。

It is important to remember that C# abstracts away the concept of pointers in most cases so that you can safely think of obj1 and obj2 as being List<string> and not pointers, but pointers they are.重要的是要记住 C# 在大多数情况下抽象出指针的概念,以便您可以安全地将obj1obj2视为List<string>而不是指针,而是它们的指针。

If obj1 is a member of a List, it's not available for garbage collection until the parent List is garbage collected.如果obj1是 List 的成员,则在对父 List 进行垃圾收集之前,它不能用于垃圾收集。

So:所以:

List<string> l = new List<string>();

string a = "one";
l.Add(a);

{
    string b = "two";
    l.Add(b);
}

At the end of this listing, a is in scope, b is out of scope, but both still have references in the list l , so neither are eligible for garbage collection.在此列表的末尾, a在 scope 中, b在 scope 之外,但两者仍然在列表l中具有引用,因此两者都没有资格进行垃圾回收。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM