开发者

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:

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. _mySecondObject is long -living.

The question I have is.... will the original MyObject开发者_如何学编程 ever be garbage collected? Would it be if I used 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.

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.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).


It will be garbage collected for sure. Even if you don't use 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:

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.


will the original MyObject ever be garbage collected?

Yes, it only has outgoing references here. Nothing to keep it from the GC.

The "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'.


The .NET garbage collecter will reclaim memory used by objects that are no longer reachable by any references. The reference to MyObject disappears when Go exits making the instance of MyObject eligble for garbage collection. That MyObject references a string that also has a reference stored in MySecondObject does not make any difference.


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.

If you instead would have implementeded in this way myObject would have not been released till MySecondObject is released:

private class MySecondObject {

    private MyObject myObject;

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

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜