2010-01-07 126 views
0

如何強制縮減DataTable和/或List以便我可以有效地釋放內存?我正在循環的每次迭代中從DataSet中刪除已處理的行,但我不確定內存是否正在釋放。關於處理大字符串的問題關於內存使用的問題

for (int i = m_TotalNumberOfLocalRows - 1; i >= 0; i--) 
{ 
    dr = dt.Rows[i]; 
    // Do stuff 
    dt.Rows.Remove(dr); 
} 

如果這不縮小內存中的DataTable的足跡,我可以使用List。我只使用DataTable作爲DataRows的存儲,我可以使用任何內存不足的收集或存儲機制,並且能夠每x次迭代釋放一次內存。

謝謝。



編輯: 閱讀What Are Some Good .NET Profilers?我發現,記憶的主要消費者是字符串後做一些內存分析後。

在這個過程中,我們正在做大量的用戶輸出,並且內存消耗在大約170MB-230MB之間循環,最高峯值在300MB左右。我正在使用一個初始大小爲20971520的StringBuilder來保存正在發生的事件的輸出/日誌,並且已處理完記錄總數的百分之一之後我將DevExpress MemoEdit控件的Text屬性設置爲StringBuilder.ToString ()。我發現這種方法比將StringBuilder.ToString()附加到MemoEdit.Text(顯然是在添加和設置MemoEdit.Text時StringBuilder的邏輯不同)

我也發現而不是重新創建的StringBuilder(20971520),它在記憶更容易和更快地執行,只是StringBuilder.Remove(0, StringBuilder.Length)

有沒有,你可以分享任何提示的大字符串(它寫出包含日誌文件工作時來提高性能大約30 000條記錄的日誌約爲12.2MB)?

注:我已更改問題和標籤的標題。
舊標題:如何強制收縮數據表和/或列表以釋放內存?
舊標籤:列表的DataTable C#.NET存儲

回答

1

嘗試強制垃圾收集器通:

GC.Collect(); 

如果你想確保,你的代碼會繼續執行之前的所有對象都確定下來,叫

GC.WaitForPendingFinalizers(); 

右後GC.Collect的()


編輯:正如人們在下面的評論中提到的,直接調用垃圾收集器被廣泛認爲是一種糟糕的做法。儘管如此,這仍然可以實現釋放被刪除行的未使用內存的目標。

+2

它被認爲是不好的做法,手動調用GC。你爲什麼想這樣做?讓它做它的工作。 – 2010-01-07 14:07:19

+0

如果沒有性能問題是 – 2010-01-07 14:07:19

+1

是的,我會避免調用GC.Collect - 請參閱此線程http://stackoverflow.com/questions/118633/whats-so-wrong-about-using-gc-collect/ – kd7 2010-01-07 14:09:10

0

堅持DataTable並刪除不必要的行,如你的例子。

通過這樣做,您無法控制內存使用情況:這由CLR垃圾收集器完成。

0

您是否明確需要直接管理?垃圾收集器爲你管理這個。

4

除非您遇到內存問題,否則請勿嘗試通過調用垃圾回收器手動釋放內存。運行時間將爲您處理,並且99%的時間會比您嘗試猜測最佳時間的時間更有效。

您必須記住的是,當您調用GC.Collect()時,它會針對垃圾收集的所有級別運行並「整理」需要釋放的所有對象。你很可能會花費處理器時間等處理那些不需要在那個時間點完成的事情。

如果你絕對必須的命令是GC.Collect()

http://msdn.microsoft.com/en-us/library/xe0c2357.aspx

http://www.developer.com/net/csharp/article.php/3343191/C-Tip-Forcing-Garbage-Collection-in-NET.htm

+0

謝謝凱文。正如在問題的編輯中提到的,是的程序是有內存使用問題。那麼,我認爲這是一個問題。 – AndrewJacksonZA 2010-01-08 06:49:49