2012-07-08 136 views
1

我有一個大的WinForm類,它從一個小像這樣的呼籲:C#WinForm的內存泄漏

void login() 
    {   
     mainForm f1 = new mainForm();     
     f1.ShowDialog(); 
    } 

的MainForm的將登錄(我檢查它在任務管理器)之後採取大量內存。關閉mainForm後,程序返回登錄表單。在這一步我再次檢查任務管理器,看看我的程序還沒有發佈mainForm使用的內存。一些登錄後,我的程序崩潰,並顯示「內存不足」錯誤。

我不得不說我測試了f1.Dispose(),f1 = null,GC.Collect()和我發現的每一個其他方法。

當我關閉登錄表單(在Application.Run利用其出發類)

我要摧毀MainForm的實例(F1)這種形式的所有資源,就好像當它只會釋放內存我關閉了該程序。

+0

你說你已經加了'f1.Dispose(); f1 = null; GC.Collect(); * * *之後*'f1.ShowDialog();'它不起作用?此外,它是在調試還是發佈? – 2012-07-08 14:16:40

+0

靜態事件處理程序的味道 – 2012-07-08 14:18:23

+0

是的,我檢查了我在不同論壇中找到的所有方法。並沒有發生。 – oMatrix 2012-07-08 14:29:03

回答

2

夫婦的想法:

+0

我之前使用語句檢查過,但它沒有幫助。關於其他控件,我只是使用.Net標準控件和我自己的控件,我應該說我也有一些非託管代碼。奇怪的是,當我關閉mainForm時,我沒有看到我的程序在內存使用方面有任何改變。我認爲至少它應該釋放一部分內存。關於windbg和sos,不,我會檢查它們。 – oMatrix 2012-07-08 14:38:50

+0

謝謝,我使用了內存分析器,發現了一些問題。我認爲需要一些時間才能找到所有問題。 – oMatrix 2012-07-09 10:40:08

1

也許MainForm的產生對自身的引用顯示時,檢查任何引用/代表/事件,它分配並確保它們是未註冊時的MainForm完成後,或將事件處理程序(即應用程序事件)到一個單獨的類。

到目前爲止100%的時間我「發現一個.NET內存泄漏」,它沒有!處置所有一次性物品,觀察你使用靜態參考文件所做的事情,不要重複事件訂閱,並在可能的情況下整理它們。

使用SOS作爲mouters在運行後檢查mainform類上的gcroots,並在調用GC.Collect(3)幾次後,一旦找到引用的地方,就應該找到該bug。

3

不太確定OOM與登錄表單有什麼關係。而且,關閉或處理表單會降低Taskmgr.exe報告的內存使用量。

但是你肯定是做錯了。對話框在Winforms中的處理方式不同,它不會像使用Show()顯示的窗體那樣自動放置。通常情況下,您想要在用戶輸入對話框後輸入的任何內容,這在對話框處理時會很危險。所以你必須自己做。正確的模式是:

using (mainForm f1 = new mainForm()) { 
     if (f1.ShowDialog() == DialogResult.Ok) { 
      // Retrieve data entered by user and do something with it 
      //... 
     } 
    } 

隨着使用聲明確保後檢索到的對話結果的對話實例得到處理。

+0

使用聲明並沒有幫助我。你的代碼正是我所做的。 – oMatrix 2012-07-08 15:03:25

+0

這就是我在第一句中告訴你的。你沒有記錄關於OOM狀況的任何信息。我只能假設你的代碼與其他地方的代碼類似,當然也是觸發OOM條件的一種方式。如果您不知道泄漏可能位於何處,請使用內存分析器。 – 2012-07-08 15:08:58