如下一个范类型列表,其中元素的数据类型为自定义的类MyClass
List<MyClass> _dataList = new List<MyClass>();而MyClass中又有引用类型的数据,比如假设又是一个范类型列表或其它,等等。
public class MyClass
{
List<MyOtherClass> data = new List<MyOtherClass>();
}那么对List<MyClass>类型的变量_dataList的Add、Remove、Clear等操作,实际上引用类型的数据对象没并有真正删除。
那么这样会不会出现内存中引用对象只增不减,直到程序退出?如果是这样的话,那么不是存在很大的问题哟。不知道C#的垃圾回收问题是如何处理这点的。何时删除引用类型的对象?谢谢!
List<MyClass> _dataList = new List<MyClass>();而MyClass中又有引用类型的数据,比如假设又是一个范类型列表或其它,等等。
public class MyClass
{
List<MyOtherClass> data = new List<MyOtherClass>();
}那么对List<MyClass>类型的变量_dataList的Add、Remove、Clear等操作,实际上引用类型的数据对象没并有真正删除。
那么这样会不会出现内存中引用对象只增不减,直到程序退出?如果是这样的话,那么不是存在很大的问题哟。不知道C#的垃圾回收问题是如何处理这点的。何时删除引用类型的对象?谢谢!
List<MyOtherClass> b = new List<MyOtherClass>();//比如这里创建的对象占用内存是X;
a.Add(b);
b=null;//这时X不会被回收,因为a[0]指向X
a.Clear();//这时已经没有引用指向X了,垃圾回收器会在下次执行回收的时候回收掉X
MyClass b=new 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字节内存)
那这样的话,也还是说明我上面的问题。就是,只对引用类型元素的数组、列表进行Add、Remove、Clear,这样没有真正删除对象,那么会不会存在问题,是不是在删除数组元素的时候还要先这样呀:
foreach(MyClass item in _dataList)
{
item = null;
}
然后再_dataList.Clear()呀
或者:
_dataList[index] = null;
_dataList.RemoveAt(index)
但是我看到其它人的代码通常没有这样做呀?谢谢!
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不会被回收掉.