2013-01-13 36 views
1

我從數據庫中讀取到我的Datagridview約25000條記錄。 在此閱讀,應用是在「沒有響應」的模式,我可以看到它的進程內存越來越大,並停止圍繞2500-3800 MB。 後,我關閉包含Datagridview形式,內存保持在這個規模。如何減少和如何清除內存泄漏?

我的問題是:

  1. 如何避免「沒有響應」當我讀了巨大的數據量?
  2. 如何減少我從數據庫中讀取時正在使用的內存量(我認爲我做錯了什麼,因爲它有很多內存)
  3. 如何清除I後的所有內存關閉表格?我正在處理所有我能做的事情,但似乎GC仍然沒有釋放內存..我讀了一些關於事件處理程序的信息,這些信息並不是被處置的?

從數據庫讀取的代碼到Datagridview

delegate void SetSearchCallback(); 
public void Search() 
{ 
    sqlCommand=""; 
    if (this._dbReports.InvokeRequired) 
    { 
     SetSearchCallback d = new SetSearchCallback(Search); 
     this.Invoke(d, new object[] { }); 
    } 
    else 
    { 
      DateTime startDate = new DateTime(dateTimePicker1.Value.Year, dateTimePicker1.Value.Month, dateTimePicker1.Value.Day); 
      DateTime endDate = new DateTime(dateTimePicker2.Value.Year, dateTimePicker2.Value.Month, dateTimePicker2.Value.Day); 
      sqlCommand = "select * FROM cstPackages where _dateTime >= '" + String.Format("{0:yyyy-MM-dd}", startDate) + "' and _dateTime <='" + String.Format("{0:yyyy-MM-dd} 23:59:59.999", endDate) + "' order by _dateTime desc"; //reading the db from end to start 
    } 

     if (sqlCommand != "") 
     { 
      using (SqlConnection sCon2 = new SqlConnection("Data Source=" + SettingsForm.getAddress + ";Initial Catalog=" + SettingsForm.getDatabase + ";Integrated Security=False;User Id=" + SettingsForm.getUser + ";Password=" + SettingsForm.getPassword + ";Connect Timeout=5;")) 
      { 
       try 
       { 
        sCon2.Open(); 
        using (da = new SqlDataAdapter(sqlCommand, sCon2)) 
        { 
         dsReport.Clear(); 
         da.Fill(dsReport, "cstPackages"); 
         dbBind = new BindingSource(dsReport, "cstPackages"); 
         if (firstTime == 0) 
          _dbReports.Columns.Clear(); 

         _dbReports.DataSource = dbBind; 

         if (firstTime == 0) 
         { 
          updateDataGridSettings(); 
          firstTime = 1; 
         } 

         _dbReports.Refresh(); 
         sCon2.Close(); 
         sCon2.Dispose(); 
        } 
       } 
       catch (Exception c) 
       { 
        fn.errorHandler(c.Message, SettingsForm); 
       } 
      } 
     } 
    } 
} 

,當我關閉窗體:(btnPress=1只有當我充滿了Datagridview的東西)

private void Reports_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    _dbReports.Dispose(); 
    if (btnPress == 1) 
    { 
     dsReport.Dispose(); 
     da.Dispose(); 
     dbBind.Dispose(); 
    } 
} 

而在窗體關閉後的父窗體中,我打電話給ReportForm.Dispose();

我知道Dispose沒有清除內存,但它應該有助於GC完成它的工作,對吧?

昨晚我離開了應用通宵營業(我關上了ReportForm後),並在上午的記憶是相同的(在GC沒有工作)

在先進的感謝。

編輯: 當我拿到3GB內存泄漏,我的數據庫是約5萬條記錄(我沒有注意到,因爲我有被灌我的數據庫的腳本,我忘了停下來)

現在內存泄漏是比較可以接受的,這是大約10 MB超過它以前我添加記錄到DataGridView。 不過。即使當我使用虛擬模式,並試圖關閉/處置盡我所能,每個填充內存生長在大約10 MB。

+2

你在TaskManager中看到的與GC沒有直接關係(做或不做)。除了在GUI中加載25k記錄不明智之外,這裏沒有直接指示問題。 –

+0

25K是可能的最大數量,它應該在2K左右,但我想讓應用程序達到極限並尋找錯誤。 那麼爲什麼當我用'Datagridview'關閉winform時,計算機沒有清除內存? – Itay

+0

你需要同時顯示所有這些行嗎?您的DataGridView是否處於虛擬模式?你的記憶問題何時出現?從數據庫加載或設置DataGridView的DataSource時? –

回答

1

1)如何在閱讀海量數據時避免「不響應」?

通過一個單獨的線程做這個昂貴的任務。在WinForms中,BackgroundWorker非常有用,因爲它在作業完成後自動將調用集成到主UI線程。

2)如何減少的內存量,當我從 數據庫讀取正在使用(我認爲我做錯了什麼,becude這是一個 大量的內存)

您可以嘗試啓用Virtual Mode並開始分頁數據。一次加載25000條記錄是無用的。無論如何,用戶將永遠無法與他們一起工作。

3)如何在關閉表格後清除所有內存?我正在處理 所能做的一切,但似乎GC仍然沒有釋放內存..我讀了一些關於不是 的事件處理程序?

一旦您關閉表單,垃圾收集器將負責處理所有資源。只要確保你從不存儲任何對它的引用,以便它符合GC的條件。

+0

謝謝。 我會立即檢查它。我關閉並處理了我所能做的一切,但是在關閉表單後內存仍然很大。有什麼辦法可以強制關閉所有的引用嗎? – Itay

+0

是的,確保沒有任何參考指向這個表單了。你也可以嘗試調用'GC.Collect()'立即運行垃圾收集器。但請注意,這通常是不好的做法,因爲GC知道什麼時候最適合運行而不會在應用程序中產生任何爭用。 –