2012-03-27 174 views
4

我面對一個非常奇怪的行爲。 有了這個虛擬代碼:爲什麼單個循環會導致內存泄漏?

static void Main(string[] args) 
    { 
     int i = 0; 

     while (true) 
     { 
      i++; 

      String giro = "iteration " + i; 

      Console.WriteLine(giro); 

      Thread.Sleep(40); 
     } 
    } 

使用perfom私人字節增加。

img http://dl.dropbox.com/u/2478017/memory.gif

這怎麼可能?

我以爲GC照顧這些東西。

而且,如果我比較這記憶行爲與我強迫GC收集每10次迭代版本,結果是(我)令人吃驚:

enter image description here

綠色的過程是一個沒有GC.COllect(),黑色是另一個。

你能幫我理解這個問題嗎?

謝謝!

+1

從9.5到11 MB?你擔心這個?它最終會被清理乾淨,不用擔心。 – Botz3000 2012-03-27 09:55:08

+0

問題是內存以2小時以上的方式表現出來...... – ff8mania 2012-03-27 10:06:11

+0

@ ff8mania:那是因爲你的程序非常慢,大部分時間都在睡覺。 – 2012-03-27 10:34:58

回答

9

您正在創建一串字符串。 GC還沒有看到適合收集它們。最終內存圖將平穩。 GC工作正常 - 這裏沒有問題:)

4

GC不直接整理內存。這將是非常低效的。

1

使用StringBuilder而不是String,看看是否不能解決您的問題。

1

沒有泄漏。刪除Thread.Sleep(40);並等待更長時間,GC應該在一段時間後踢。

+0

你能更好地解釋我的答案嗎? 爲什麼睡眠會影響GC? – ff8mania 2012-03-27 10:25:58

+1

@ ff8mania:我說刪除sleep可以更快地創建String對象以更快地查看它對內存的影響。通過這種方式,您可以看到它是無限期填充內存(真正的泄漏)還是僅僅是虛擬機或GC行爲的人爲因素。我不認爲你的程序泄漏任何東西。 – mdakin 2012-03-27 10:30:26

+0

Exactlu。它會變得平靜。不是真正的泄漏。 – ff8mania 2012-03-27 13:06:03

0

嘗試改變這一點:

String giro = "iteration " + i; 
Console.WriteLine(giro); 

Console.WriteLine("iteration " + i); 
0

如果你需要垃圾收集器,你可以把它叫做:

     GC.Collect(); 
         GC.WaitForPendingFinalizers(); 

...它非常昂貴,但..

0

如果您定義爲轉出迴圈 它會解決你的問題

String giro; 

    while (true) 
    { 
     i++; 

     giro = "iteration " + i; 

     Console.WriteLine(giro); 

     Thread.Sleep(40); 
    }