简体   繁体   English

字符串,引用和垃圾回收

[英]Strings, references, and Garbage Collection

Imagine you have an object that has several properties. 假设您有一个具有多个属性的对象。 One of these properties is a string: 这些属性之一是字符串:

private class MyObject
{
    public string PropertyOne {get; set;}
    ...
}

I now create a new object, based on the contents on MyObject : 我现在根据MyObject上的内容创建一个新对象:

private class MySecondObject
{
    public string PropertyOneCopy {get; set;}

    public MySecondObject(MyObject myObject)
    {
        this.PropertyOneCopy = myObject.PropertyOne;
        ....
    }
}

In the calling scenario we have: 在调用场景中,我们有:

private class Scenario
{
    private MySecondObject _mySecondObject;

    public void Go()
    {
        MyObject myObject = new MyObject();
        myObject.PropertyOne = "Hello, World!";

        _mySecondObject = new MySecondObject(myObject);
    }
}

The original instance of MyObject now falls out of scope. MyObject的原始实例现在不在范围内。 _mySecondObject is long -living. _mySecondObject长期存在。

The question I have is.... will the original MyObject ever be garbage collected? 我的问题是……原始MyObject会被垃圾收集吗? Would it be if I used this.PropertyOneCopy = String.Copy(myObject.PropertyOne); 如果我使用this.PropertyOneCopy = String.Copy(myObject.PropertyOne); ?

The object that used to be in myObject will be garbage collected normally, because there is no outstanding reference to it. 以前位于myObject的对象将正常进行垃圾回收,因为没有未引用的对象。

There is still a reference to the string object that used to be the value of the PropertyOne property of myObject , but that will only prevent the string from being reclaimed, not the whole MyObject instance. 仍然有一个对string对象的引用,该引用以前是myObjectPropertyOne属性的值,但是这只会阻止回收该字符串 ,而不是整个MyObject实例。

String.Copy does nothing special, it's simply there to serve as a constructor that accepts a string instance and creates a duplicate object ( System.String has no such constructor). String.Copy没什么特别的,它只是用作接受string实例并创建重复对象的构造函数( System.String没有此类构造函数)。

It will be garbage collected for sure. 肯定会收集垃圾。 Even if you don't use String.Copy. 即使您不使用String.Copy。

The string has no references to any other objects... instead, what you have is an object tha has a reference to a string... what happens to that string has nothing to do with objects that have reference to that same string. 该字符串没有对任何其他对象的引用...相反,您拥有的是一个对象,它具有对字符串的引用...该字符串发生的情况与引用该相同字符串的对象无关。

Example: 例:

If you have objects A, B, and C, all of them have a string property assigned like this: 如果您有对象A,B和C,则所有对象均具有如下分配的字符串属性:

string s = "str";
A.Str = s;
B.Str = A.Str;
C.Str = B.Str;

is the same as doing: 与执行相同:

string s = "str";
A.Str = s;
B.Str = s;
C.Str = s;

When A is no longer used, it can die, without influencing the other objects, even if they share the same string. 当不再使用A时,即使它们共享相同的字符串,它也可以死而不会影响其他对象。

will the original MyObject ever be garbage collected? 原始MyObject会被垃圾回收吗?

Yes, it only has outgoing references here. 是的,此处仅具有传出引用。 Nothing to keep it from the GC. 没有什么可以阻止它。

The "Hello, World!" "Hello, World!" string is co-owned and will stay alive as long as 1 of the objects is alive. 字符串是共同拥有的,只要其中一个对象处于活动状态,它将保持活动状态。

Using the GC is easier than you seem to think, you almost never have to 'help'. 使用GC比您想像的要容易,几乎不需要“帮助”。

The .NET garbage collecter will reclaim memory used by objects that are no longer reachable by any references. .NET垃圾收集器将回收由任何引用不再可访问的对象使用的内存。 The reference to MyObject disappears when Go exits making the instance of MyObject eligble for garbage collection. Go退出时,对MyObject的引用将消失,从而使MyObject的实例适合进行垃圾收集。 That MyObject references a string that also has a reference stored in MySecondObject does not make any difference. MyObject引用的字符串也具有存储在MySecondObject中的引用,这没有任何区别。

MySecondObject has a reference to the string in MyObject, not to the MyObject-object itself, so myObject will be released to the GC as soon as you exit the Go-function, so no need to worry. MySecondObject引用了MyObject中的字符串,而不是MyObject对象本身,因此,一旦退出Go函数,myObject将被释放到GC,因此不必担心。

If you instead would have implementeded in this way myObject would have not been released till MySecondObject is released: 如果您改为以这种方式实现,则在发布MySecondObject之前不会发布myObject:

private class MySecondObject {

    private MyObject myObject;

    public string PropertyOneCopy {
        get{
            return myObject.PropertyOne;
        }
    }

    public MySecondObject(MyObject myObject)     {
        myObject = myObject.PropertyOne;
        ....
    }
}

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

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