2010-07-05 41 views
0

我在我的程序中的錯誤,所以我做了一些實驗,發現下面的代碼最終.NET位圖的問題

運行一段時間後拋出異常。

while (1) 
{ 
    System::Drawing::Bitmap^ pBitmap = gcnew System::Drawing::Bitmap(500, 500); 
    this->Cursor = gcnew System::Windows::Forms::Cursor(pBitmap->GetHicon()); 
} 

我找不到這個例外的任何線索。

怎麼了?

所以我的代碼更改爲這個

while (1) 
{ 
    System::Drawing::Bitmap^ pBitmap = gcnew System::Drawing::Bitmap(500,500);         
    System::Windows::Forms::Cursor^ pCursor = gcnew System::Windows::Forms::Cursor(pBitmap->GetHicon());                

    delete pBitmap; 
    delete pCursor;     
} 

同樣的例外還是被拋出。

任何線索都會很感激。

+0

什麼是異常? – 2010-07-05 08:27:54

+0

1.什麼是確切的例外? 2.我會調用''pBitmap''對象的'Dispose'方法。 – 2010-07-05 08:29:03

+0

例外情況是: System.Drawing.dll中發生未經處理的類型爲「System.Runtime.InteropServices.ExternalException」的異常 附加信息:GDI +中發生了一般性錯誤。 – shawn 2010-07-05 08:35:01

回答

2

當您創建位圖時,您請求內存(500 * 500 * bytesPerPixeL)和內部GDI句柄。可用手柄的數量相當大,但有限。所以,我的猜測是,在垃圾收集器啓動之前或者GDI手柄用完時,你要麼耗盡內存。

您應該使用using(pBitmap = ...)來自動調用Dispose()或在完成後手動調用Dispose()。光標也一樣。

MSDN文章GDI Objects說:

「有65,536每個會話GDI處理的理論極限。然而,GDI的句柄的最大數量,可以每個會話打開通常較低,因爲它是由影響。有效內存。」

+0

但是Bitmap和Cursor都沒有配置方法 – shawn 2010-07-05 08:46:53

+0

@shawn:這些類的'IDisposable'是使用顯式接口實現實現的。您必須投射到該界面才能使用它。 – 2010-07-05 08:52:43

0

我重建的問題,它看起來像這樣: Screenshot

當我看了看任務管理器,我的內存消耗運行程序的第5000運行得來,而看起來像我的預期。該圖形正在增長,同時爲新圖像分配內存,而在GC釋放內存的同時減少了內存 - 然而,釋放內存似乎從來都不是完美的,因爲在下降期間下降的值不斷上升。這使我相信你有某種記憶力衰退。

- 所以,我的福爾摩斯技能受到了侮辱,我的科倫坡技能接管了。什麼可能導致這樣的泄漏?嗯..忘記打電話了.Dispose()?是的,位圖確實實現了IDisposable,所以,你應該記得在你創建一個新的位圖之前調用.Dispose():)