本篇主要着眼于C#中的垃圾回收和资源管理机制,这是C#宣传中最优于C++的长处,值得好好领悟一下。
- Value Type在创建其的方法结束的时候被销毁和回收;reference type只有在没有任何引用后才可以被销毁。
- Object的创建分为两步:1-new操作在heap中分配内存,这一步是不可控制的;2-new操作使用构造函数将内存转换为object。Object的销毁则正好相反,先调用析构函数,再释放内存,这个过程被称为garbage collection。
- C#中不允许重载new;C#中没有delete操作符,你永远不能手动销毁一个Object;
- 析构函数不能用于struct;析构函数不能使用public等修饰符,也不能有参数;编译器自动将析构函数转换为对Object.Finalize的override
class Tally
{
~Tally() { ... }
}
Into this:
class Tally
{
protected override void Finalize()
{
try { ... }
finally { base.Finalize(); }
}
}
- Garbage collection发生的时间是不确定的,即使你调用了System.GC.Collect(),也无法确认object是否被销毁;Object被销毁的顺序是不确定的。
- Garbage collection在独立的thread中运行,当它运行的时候,其他thread都会暂停,其运行过程为:1-构造一个所有可访问object的映射表;2-检查所有的不可访问object是否有析构函数,有析构函数的object被放于freachable queue中;3-将所有不在queue中的object释放,对heap进行defragment并更新对object的引用;4-在另外一个thread中处理queue中的object。
- 在class中包含析构函数会增加复杂性减慢速度,应该尽量避免,析构函数之间不能有依赖关系。
- 为了能够在确定的时间释放某些关键资源,这时候就需要在class中实现disposal方法;要确保disposal方法即使发生了exception也会被执行,这可以通过using语句(using ( type variable = initialization ) embeddedStatement)完成:using语句会在语句块结束的时候自动调用object的Dispose方法
using (TextReader reader = new StreamReader(filename))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
Using语句的实际效果是
{
TextReader reader = new StreamReader(filename);
try
{
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
finally
{
if (reader != null)
{
((IDisposable)reader).Dispose();
}
}
}
- 在using语句中声明的变量必须实现了IDisposable接口
namespace System
{
interface IDisposable
{
void Dispose();
}
}
- 你可以通过在析构函数中调用Dispose方法来确保资源一定被释放了,这是一种有益的保护措施;Dispose方法必须是public的,可以在任何时候被调用。
class Example : IDisposable
{
...
~Example()
{
Dispose();
}
public virtual void Dispose()
{
if (!this.disposed)
{
try {
// release scarce resource here
}
finally {
this.disposed = true;
GC.SuppressFinalize(this);//使garbage collector不调用本object的析构函数
}
}
}
public void SomeBehavior() // example method
{
checkIfDisposed();
...
}
...
private void checkIfDisposed()
{
if (this.disposed)
{
throw new ObjectDisposedException("Example");
}
}
private Resource scarce;
private bool disposed = false;
}
(待续,下一篇将描述Properties、Indexer等高级应用)