字符串、引用和垃圾回收

4

想象一下,您有一个具有多个属性的对象。其中一个属性是字符串:

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

我现在创建一个新的对象,基于 MyObject 的内容:
private class MySecondObject
{
    public string PropertyOneCopy {get; set;}

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

在调用场景中,我们有以下内容:
private class Scenario
{
    private MySecondObject _mySecondObject;

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

        _mySecondObject = new MySecondObject(myObject);
    }
}

原始的MyObject实例现在超出范围。 _mySecondObject是长期存在的。

我有的问题是...原始的MyObject会被垃圾回收吗?如果我使用this.PropertyOneCopy = String.Copy(myObject.PropertyOne);,它会被垃圾回收吗?

5个回答

4

因为没有任何未释放的引用,所以曾经存在于myObject中的对象将被正常垃圾回收。

曾经是myObjectPropertyOne属性值的string对象仍然有一个引用,但这只会阻止string被回收,而不是整个MyObject实例。

String.Copy没有任何特殊之处,它只是作为一个构造函数存在,接受一个string实例并创建一个副本对象(System.String没有这样的构造函数)。


3

它一定会被垃圾回收。即使您不使用String.Copy。

该字符串没有对任何其他对象的引用...相反,您拥有一个引用到字符串的对象...该字符串发生的事情与具有对该字符串的引用的对象无关。

例如:

如果您有A、B和C三个对象,它们都分配了一个字符串属性,如下所示:

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

这与执行以下操作相同:

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

当A不再使用时,即使它们共享同一个字符串,也不会影响其他对象,可以安全地销毁。


1
原始的MyObject会被垃圾回收吗?
是的,这里只有出站引用。没有任何东西可以阻止它被GC回收。
“Hello, World!”字符串是共同拥有的,并且只要其中一个对象存活,它就会保持活动状态。
使用GC比你想象的要容易得多,你几乎不需要“帮助”。

0

MySecondObject引用了MyObject中的字符串,而不是MyObject对象本身,因此一旦退出Go函数,myObject将被释放到GC中,所以不需要担心。

如果您以这种方式实现,那么只有在MySecondObject被释放时,myObject才会被释放:

private class MySecondObject {

    private MyObject myObject;

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

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

0
.NET垃圾回收器将回收任何引用都无法访问的对象所使用的内存。当Go退出时,对MyObject的引用消失,使得MyObject的实例有资格进行垃圾回收。MyObject引用了一个字符串,该字符串也在MySecondObject中存储了一个引用,这并不会产生任何影响。

MySecondObject 不持有该引用,它仅在构造函数的持续时间内使用它。 - Adam Houldsworth
你在哪里看到 MySecondObject 存储了对 MyObject 的引用?它只存储一个字符串。 - user395760

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接