讀到一篇文章
public void TestGdiLeak()
{
Bitmap bmp = new Bitmap(
Graphics g = Graphics
Brush brush = new LinearGradientBrush
(new PointF(
new PointF(
Color
for (int j =
for(int i = 0; i < 60; ++i)
g.FillEllipse(brush, i * 10, j * 10, 10, 10);
this.CreateGraphics().DrawImage(bmp, 0, 0);
}
要測試上述代碼,進行如下操作:
新建一個Windows Application(C# Form)應用;
將TextGdiLeak添加為Form1的成員;
在Form1上放置一個Timer timer1,將其Interval設為10;
在Form1構造函數中調用timer1.Start();
在timer1的Tick事件處理函數中調用TestGdiLeak方法);
在適當的地方調用timer1.Stop()。Tw.wINGwIT.Com
編譯運行該應用,打開“Windows任務管理器”檢查其進程,發現內存使用率不停地上升。顯然,是GDI+使用不當造成的。初步猜測為在每次timer1的Tick事件調用該方法時,Bitmap對象沒有被及時地垃圾收集掉。嘗試將代碼修改為:
public void TestGdiLeak()
{
using (Bitmap bmp = new Bitmap(600, 600))
{
Graphics g = Graphics.FromImage(bmp);
Brush brush = new LinearGradientBrush
(new PointF(0.0f, 0.0f),
new PointF(700.0f, 300.0f),
Color.Blue, Color.Red);
for (int j = 0; j < 60; ++j)
for(int i = 0; i < 60; ++i)
g.FillEllipse(brush, i * 10, j * 10, 10, 10);
this.CreateGraphics().DrawImage(bmp, 0, 0);
}
}
再次編譯運行,發現情況並沒有好轉。猜測Graphics對象g可能也沒有被及時收集,同時由於g與bmp有關聯,也影響了bmp的收集。再將代碼修改為:
public void TestGdiLeak()
{
using (Bitmap bmp = new Bitmap(600, 600))
{
using (Graphics g = Graphics.FromImage(bmp))
{
Brush brush = new LinearGradientBrush
(new PointF(0.0f, 0.0f),
new PointF(700.0f, 300.0f),
Color.Blue, Color.Red);
for (int j = 0; j < 60; ++j)
for(int i = 0; i < 60; ++i)
g.FillEllipse(brush, i * 10, j * 10, 10, 10);
this.CreateGraphics().DrawImage(bmp, 0, 0);
}
}
}
再次編譯運行,內存使用率已穩定在一個常數范圍內。
由此可見GDI+使用中(其他.Net對象也一樣)要十分小心類似的情況,.Net Framework可以非常好地工作,前提是程序員寫的代碼足夠符合其機制。對於資源對象,象上述代碼中一樣使用using能保證它們被及時的垃圾收集(當然使用using的對象必須IDispose接口)。針對上例還有另外一種簡單的解決方法,就是將Bitmap、Graphics等對象抽出TestGdiLeak方法作為Form1的類成員,並只對它們進行一次new操作
From:http://tw.wingwit.com/Article/os/youhua/201311/10788.html