如下一个范类型列表,其中元素的数据类型为自定义的类MyClass
List<MyClass> _dataList = new List<MyClass>();而MyClass中又有引用类型的数据,比如假设又是一个范类型列表或其它,等等。
public class MyClass
{
List<MyOtherClass> data = new List<MyOtherClass>();
}那么对List<MyClass>类型的变量_dataList的Add、Remove、Clear等操作,实际上引用类型的数据对象没并有真正删除。
那么这样会不会出现内存中引用对象只增不减,直到程序退出?如果是这样的话,那么不是存在很大的问题哟。不知道C#的垃圾回收问题是如何处理这点的。何时删除引用类型的对象?谢谢!

解决方案 »

  1.   

    List<MyClass> a = new List<MyClass>();
    List<MyOtherClass> b = new List<MyOtherClass>();//比如这里创建的对象占用内存是X;
    a.Add(b);
    b=null;//这时X不会被回收,因为a[0]指向X
    a.Clear();//这时已经没有引用指向X了,垃圾回收器会在下次执行回收的时候回收掉X
      

  2.   

    上面写错了,应该是
    MyClass b=new MyClass();
      

  3.   

    List<MyClass> a = new List<MyClass>();
    MyClass b=new MyClass();//比如这里创建的对象占用内存是X;
    a.Add(b);
    b=null;//这时X不会被回收,因为a[0]指向X
    a.Clear();//这时已经没有引用指向X了,垃圾回收器会在下次执行回收的时候回收掉X//当X被回收掉以后,X内的成员当然也会被回收掉,data也就没,所以data创建的那块内存Y也没引用指向了,也会被回收掉了.关键一点是,你别把类实例对象当作一块内存,它只是一个引用集(指针集),即它的成员也是一个引用,比如List的Remove和Clear方法只是用来清除引用(指针)的,不是负责清除内存的.
    (虽然引用本身占4字节内存)
      

  4.   

    谢谢he_8134() !
    那这样的话,也还是说明我上面的问题。就是,只对引用类型元素的数组、列表进行Add、Remove、Clear,这样没有真正删除对象,那么会不会存在问题,是不是在删除数组元素的时候还要先这样呀:
    foreach(MyClass item in _dataList)
    {
    item = null;
    }
    然后再_dataList.Clear()呀
    或者:
    _dataList[index] = null;
    _dataList.RemoveAt(index)
    但是我看到其它人的代码通常没有这样做呀?谢谢!
      

  5.   

    不用的,一个对象被回收了,它的子对象也会被回收~~~比如
    List list=new List();
    list.Add(new Object());
    list.Add(new Object());
    list.Add(new Object());
    list.Clear();//或者是list=null;
    //所有new Object()创建的内存也将被回收
    反正记住两点:
    1.对象被收回的话,对象内的成员(即所有引用指针)也将被销毁,如果有以下状况这里也不用管,
    List list=new List();//new List()创建内存内对象 X
    list.Add(new Object());//new Object()创建内存内对象 Y
    Object obj=list[0];//obj也指向Y
    list=null;//这样X没有引用指向它了,所以X会被回收掉,而子引用list[0]这个引用也会被销毁,你完全可以看作.net虚拟机帮你做了list[0]=null;2.垃圾回收机回收没有引用指向的内存对象,上那种情况由于obj指向了Y,所以Y不会被回收掉.
      

  6.   

    list=null不会导致list[0]=null,但是X被回收的话就会了.