最近敝人在WinCE-based上開發的模組越來越龐大,另一方面是IO處理頻繁,執行一兩天就會因資源不足導致Shutdown。沒錯,資源對於WinCE而言一直都是相當棘手的問題,畢竟WinCE的記憶體和虛擬記憶體空間都不像桌上型電腦龐大,可以想怎麼用就怎麼用。因此,當我們針對WinCE模組設計時,除了程式資源分配盡量優化外,更重要的是需考慮其模組資源上的使用與釋放,如此的系統才能經的起長時間的考驗。以下是網路一篇文章,我覺得很淺顯易懂,在此就暫時引用一下這位高手的文獻,供大家參考:
(作者:史帝芬)
.Net framework和Java VM一樣針對一般資源會自動回收,對於
unmanaged的資源,Java會於finalize
做處理,語法上C#和C++相同,作法上則和Java相同,都是交給VM處理。
事實上,C#也有個Finalize method,這個method與Java的finalize相同,於物件將被回收時會被
VM呼叫。C#的編譯器在編譯時實際上會將解構子轉換成Finalize的覆載method,如下所示。
class MyClass
{
~MyClass() { ... }
}
會轉換成:
class MyClass
{
protected override void Finalize()
{
try { ... }
finally { base.Finalize(); }
}
}
C#提供了與C++一樣語法的解構子,當object消失時,.Net framework
會執行解構子,我們可於此時加入程式進行資源回收,與Java相同的是,什麼時候object會消失?
這由VM決定,並非在object變成null時,VM即會立刻執行解構子並回收object。底下範例程式1.1可以看出,.Net framework
會先建構父類別再建構子類別,解構時則會以反方向,先解構子類別,再解構父類別,特別注意的
是,解構子不需由程式呼叫,.Net framework會自動執行。
如果要強迫.Net framework資源回收,可以使用如範例程式1.2的方法,
以GC指令強迫.Net framework資源回收,並使用WaitForPendingFinalizers method等到確實回收後
再繼續執行,因為資源回收時是在另一個thread之故。
* 範例程式 1.1
using System;
namespace Garbage
{
class Father
{
public Father()
{
Console.WriteLine("建構 Father");
}
~Father()
{
Console.WriteLine("解構 Father");
}
}
class Son : Father
{
public Son()
{
Console.WriteLine("建構 Son");
}
~Son()
{
Console.WriteLine("解構 Son");
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("程式開始");
Son me = new Son();
me = null;
Console.WriteLine("程式結束");
}
}
}
* 執行結果 1.1
程式開始
建構 Father
建構 Son
程式結束
解構 Son
解構 Father
* 範例程式 1.2
using System;
namespace Garbage
{
class Father
{
public Father()
{
Console.WriteLine("建構 Father");
}
~Father()
{
Console.WriteLine("解構 Father");
}
}
class Son : Father
{
public Son()
{
Console.WriteLine("建構 Son");
}
~Son()
{
Console.WriteLine("解構 Son");
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("程式開始");
Son me = new Son();
me = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("程式結束");
}
}
}
* 執行結果 1.2
程式開始
建構 Father
建構 Son
解構 Son
解構 Father
程式結束
IDisposable介面僅有一個method -- Dispose,實作IDisposable
介面後,在using中.Net framework將會自動呼叫Dispose method回收資源,如範例程式 2.1
所示。但是由執行結果2.1各位是否看出端倪? .Net framework只呼叫子類別的Dispose method
卻沒有呼叫父類別的Dispose method,所以,實作IDisposable介面時,父類別的資源回收要
由子類別呼叫,請看範例程式2.2。
範例程式 2.3是讓各位了解,實作IDisposable介面在using中.Net
framework會自動呼叫Dispose method進行資源回收,但是在一般狀況下並不會。需要程式自行
呼叫Dispose method或是改成如範例程式 2.4所示,其中GC.SuppressFinalize(this)是通知
.Net framework不要再對這個object進行資源回收,如果不這麼做,當主程式中自行呼叫Dispose method,
.Net framework又於object消失後執行解構子,會造成Dispose method重複執行。
* 範例程式 2.1
using System;
namespace Garbage2
{
class Father : IDisposable
{
public Father()
{
Console.WriteLine("建構 Father");
}
public void Dispose()
{
Console.WriteLine("解構 Father");
}
}
class Son : Father, IDisposable
{
public Son()
{
Console.WriteLine("建構 Son");
}
new public void Dispose()
{
Console.WriteLine("解構 Son");
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("程式開始");
using (Son me = new Son())
{
Console.WriteLine("程式執行中");
}
Console.WriteLine("程式結束");
}
}
}
* 執行結果 2.1
程式開始
建構 Father
建構 Son
程式執行中
解構 Son
程式結束
* 範例程式 2.2
using System;
namespace Garbage2
{
class Father : IDisposable
{
public Father()
{
Console.WriteLine("建構 Father");
}
public void Dispose()
{
Console.WriteLine("解構 Father");
}
}
class Son : Father, IDisposable
{
public Son()
{
Console.WriteLine("建構 Son");
}
new public void Dispose()
{
Console.WriteLine("解構 Son");
base.Dispose();
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("程式開始");
using (Son me = new Son())
{
Console.WriteLine("程式執行中");
}
Console.WriteLine("程式結束");
}
}
}
* 執行結果 2.2
程式開始
建構 Father
建構 Son
程式執行中
解構 Son
解構 Father
程式結束
* 範例程式 2.3 (僅有主程式,其餘請參考2.2)
class Program
{
static void Main(string[] args)
{
Console.WriteLine("程式開始");
Son me = new Son();
me = null;
Console.WriteLine("程式結束");
}
}
* 執行結果 2.3
程式開始
建構 Father
建構 Son
程式結束
* 範例程式 2.4
using System;
namespace Garbage2
{
class Father : IDisposable
{
public Father()
{
Console.WriteLine("建構 Father");
}
public void Dispose()
{
Console.WriteLine("解構 Father");
GC.SuppressFinalize(this);
}
~Father()
{
Dispose();
}
}
class Son : Father, IDisposable
{
public Son()
{
Console.WriteLine("建構 Son");
}
new public void Dispose()
{
Console.WriteLine("解構 Son");
GC.SuppressFinalize(this);
}
~Son()
{
Dispose();
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("程式開始");
Son me = new Son();
me = null;
Console.WriteLine("程式結束");
}
}
}
* 執行結果 2.4
程式開始
建構 Father
建構 Son
程式結束
解構 Son
解構 Father
全站熱搜