尽早地将变量置null?
用C++的开发者大多养成了尽早释放资源的好习惯,在转移到dotNet平台后,也要坚持将用完的引用型变量置null,以便GC能够尽快地回收内存。果真如此吗?
DotNet的GC是分代式的,目前是四代,生存期最长的在第一代,最短的同时也是最近分配的在第四代。第四代的空间很小,不到一兆。GC在尝试分配内存失败时才启动一次回收,绝大多数的回收只发生在第四代,因为其空间小,回收的花的时间也很少。
以以下代码为例:
void Foo()
{
string str = DateTime.Now.ToString();
Console.WriteLine(str);
str = null;
for (int i=0; i<10; i++)
Console.WriteLine(i);
}
在Debug模式下,str的生存期由构造出来到以上函数运行结束,这时将str置null确实可以让对象提早适合回收。但在Release模式下,str的生存期只到计算完Console.WriteLine()的参数之后,也就是说str = null完全是多余的,并且编译器也会把它优化掉。
所以,用完的局部变量置null是徒劳的。
但对实现IDisposable接口的类,在Dispose()时将引用类型的数据成员置null是有意义的。因为尽管对象已经被Dispose了,但还有可能有对该对象的引用,使它暂时还不能被回收。