垃圾回收器的工作原理
當(dāng)對(duì)象不再被引用時(shí),對(duì)象銷(xiāo)毀分兩步走,過(guò)程如下:
1.CLR執(zhí)行清理工作,可以定一個(gè)析構(gòu)器來(lái)加以控制
2.CLR將對(duì)象占用的內(nèi)存歸還給堆 ,解除對(duì)象內(nèi)存分配。對(duì)這個(gè)階段你沒(méi)有控制權(quán)。
垃圾回收器在它自己的線(xiàn)程中運(yùn)行,而且只在特定的時(shí)候才會(huì)執(zhí)行。它運(yùn)行時(shí),應(yīng)用程序中運(yùn)行的其他線(xiàn)程將暫停。這是由于垃圾回收器可能需要移動(dòng)對(duì)象并更新對(duì)象引用。如果對(duì)象仍在使用,這些操作就無(wú)法執(zhí)行。
編寫(xiě)析構(gòu)器
使用析構(gòu)器(destructor),可在對(duì)象被垃圾回收時(shí)執(zhí)行必要的清理。
使用場(chǎng)景:
1.如果托管資源很大(比如一個(gè)多維數(shù)組),就可以考慮將該資源的所有引用都設(shè)為null,使資源能被立即清理。
2.對(duì)象引用了非托管資源(無(wú)論直接還是間接),析構(gòu)器就更有用了。間接的非托管資源,如文件流、網(wǎng)絡(luò)連接、數(shù)據(jù)庫(kù)連接和其他由Windows操作系統(tǒng)管理的資源。
析構(gòu)器的語(yǔ)法:先寫(xiě)一個(gè)~符號(hào),再添加類(lèi)名。
析構(gòu)器的限制:
1.只適用于引用類(lèi)型。
2.不能為析構(gòu)器指定訪(fǎng)問(wèn)修飾符。這是由于永遠(yuǎn)不在自己的wack調(diào)用析構(gòu)器,總是由垃圾回收器幫你調(diào)用?
3.析構(gòu)器不能獲取任何參數(shù)。這同樣是由于永遠(yuǎn)不由你自己調(diào)用。
資源管理
使用try...finally語(yǔ)句
TextReader reader = new StreamReader(filename);
try
{
? ? string line;
? ? while((line = reader.ReadLine()) != null)
? ? {
? ? ? ? Console.WriteLine(line);
? ? }
}
finally
{
? ? reader.close();
}
使用using語(yǔ)句和IDisposable接口
using語(yǔ)句提供了一個(gè)脈絡(luò)清晰的機(jī)制來(lái)控制資源的生存期??蓜?chuàng)建一個(gè)對(duì)象,此對(duì)象在using語(yǔ)句塊結(jié)束時(shí)銷(xiāo)毀。
using(type variable = initialization)
{
? ? statementBlock
}
using語(yǔ)句聲明的變量的類(lèi)型必須實(shí)現(xiàn)IDisposable接口。
析構(gòu)器中調(diào)用Dispose方法
定自己的類(lèi)時(shí),如何保證資源得到釋放呢?你可以使用:
1.實(shí)現(xiàn)IDisposable接口,使用using語(yǔ)句
2.自定義析構(gòu)器
3.實(shí)現(xiàn)IDisposable接口,自定義析構(gòu)器,在析構(gòu)器中調(diào)用Dispose方法。
class Example : IDisposable
? ? {
? ? ? ? private Resource scarce;
? ? ? ? private bool disposed = false;
? ? ? ? ~Example()
? ? ? ? {
? ? ? ? ? ? this.Dispose(false);
? ? ? ? }
? ? ? ? public virtual void Dispose()
? ? ? ? {
? ? ? ? ? ? this.Dispose(true);
? ? ? ? ? ? GC.SuppressFinalize(this);
? ? ? ? }
? ? ? ? protected virtual void Dispose(bool disposing)
? ? ? ? {
? ? ? ? ? ? if (!this.disposed)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (disposing)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? this.disposed = true;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? public void SomeBehaviro()
? ? ? ? {
? ? ? ? ? ? checkIfDisposed();
? ? ? ? }
? ? ? ? private void checkIfDisposed()
? ? ? ? {
? ? ? ? ? ? if (this.disposed)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? throw new ObjectDisposedException("示例:對(duì)象已經(jīng)清理");
? ? ? ? ? ? }
? ? ? ? }
? ? }