2012-03-27 176 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); 
    }