为什么GC不收集未使用的对象?

时间:2012-01-02 15:30:03

标签: c# memory-management producer-consumer

我为我的实验用BlockingCollection实现了Producer / Consumer模式。

PerformanceCounter c = null;
void Main()
{
    var p  =System.Diagnostics.Process.GetCurrentProcess();
    c = new PerformanceCounter("Process", "Working Set - Private", p.ProcessName);

    (c.RawValue/1024).Dump("start");
    var blocking = new BlockingCollection<Hede>();
    var t = Task.Factory.StartNew(()=>{
        for (int i = 0; i < 10000; i++)
        {
            blocking.Add(new Hede{
            Field = string.Join("",Enumerable.Range(0,100).Select (e => Path.GetRandomFileName()))
            });
        }
        blocking.CompleteAdding();
    });

    var t2 = Task.Factory.StartNew(()=>{
        int x=0;
        foreach (var element in blocking.GetConsumingEnumerable())
        {
            if(x % 1000==0)
            {
                (c.RawValue/1024).Dump("now");
            }
            x+=1;   
        }
    });
    t.Wait();
    t2.Wait();
    (c.RawValue/1024).Dump("end");
}

运行后我的内存转储:

start
211908
now
211972
now
212208
now
212280
now
212596
now
212736
now
212712
now
212856
now
212840
now
212976
now
213036
end
213172

在消费之前我的记忆是211908kb,但是从其他线程产生时它一个接一个地增加。

GC没有从内存中收集生成的对象。为什么我的内存增量虽然实现了生产者/消费者模式?

2 个答案:

答案 0 :(得分:6)

ConcurrentQueue<T> contains a memory leak in .Net 4.0默认使用的BlockingCollection<T>。我不确定这是你观察到的问题,但可能是。

应该在即将发布的.Net 4.5中修复。

答案 1 :(得分:0)

垃圾收集器不会一直自动释放内存。您可以在处置未使用的对象后调用GC.Collect();来强制进行垃圾回收。