还在收集对象的范围 - GC.Collect的 [英] Collect objects still in scope - GC.Collect

查看:124
本文介绍了还在收集对象的范围 - GC.Collect的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看了这篇文章:的http:// blogs.msdn.com/b/oldnewthing/archive/2010/08/10/10048149.aspx 并老实说,我不明白,每一个细节。据我了解C以下的code就算我不设置C为空应收集。另一件事是,分配一个foreach期间发生的事情似乎不是只要我们释放了在同一个函数的范围。 (参见下面的例子)

I have read this article: http://blogs.msdn.com/b/oldnewthing/archive/2010/08/10/10048149.aspx and honestly I don't understand every detail. As far as i understand in the code below c should be collected even if i don't set c to null. Another thing is that allocations happening during a foreach seem to be not freed as long as we in the scope of the same function. (See example below)

class Program
{
    public class SomeClass
    {
        public byte[] X;

        public SomeClass()
        {
            X = new byte[1024 * 1024 * 100];
            X[155] = 10;
        }
    }

    static void Main()
    {
        Console.WriteLine("Memory: " + GC.GetTotalMemory(false));

        SomeClass c;
        c = new SomeClass();

        Console.WriteLine("Memory: " + GC.GetTotalMemory(false));
        GC.Collect();
        Console.WriteLine("Memory: " + GC.GetTotalMemory(true));
        Console.ReadKey();

        /*
         * Output:
         * 
         * Memory: 186836
         * Memory: 105044468
         * Memory: 104963676
         * 
         */
    }
}

修改作为第一个例子中的解决方案:在调试模式(在调试器没有运行,但即使编译模式)。如果我用版本,它会按预期:C收集即使不设置为NULL。对于第二个例子同样适用。

EDIT The solution for the first example: The Debug-Mode (not running in debugger but even the compilation-mode). If I use Release it'll work as expected: c is collected even without setting to null. For Second example the same applies.

第二个例子

static void Main(string[] args)
{
    Console.WriteLine("Startup Memory: " + GC.GetTotalMemory(false));

    var obj = BOObject.Get();

    Console.WriteLine("Fetched Object: " + GC.GetTotalMemory(false));
    GC.Collect();
    Console.WriteLine("Fetched Object (Collected): " + GC.GetTotalMemory(false));

    foreach (var node in obj.Traverse())
    {
        string name = node.Name;
    }

    Console.WriteLine("Traversed: " + GC.GetTotalMemory(false));
    GC.Collect();
    Console.WriteLine("Traversed (collected): " + GC.GetTotalMemory(false));

    obj = null;

    GC.Collect();
    Console.WriteLine("collected: " + GC.GetTotalMemory(true));
    Console.Read();
}

输出:

启动内存:193060 牵强:8972464 取(收集):5594308 走过:272553096 走过(收集):269564660 收集:269564048

Startup Memory: 193060 Fetched: 8972464 Fetched (Collected): 5594308 Traversed: 272553096 Traversed (collected): 269564660 collected: 269564048

如果我把foreach循环的另一个功能,调用这个函数.Collect后使用内存调用约5800000.那么为什么垃圾不收集时,我有相同功能的foreach循环?

If i put the foreach loop in another function and call this function the memory used after .Collect is call is about 5800000. So why the garbage is not collected when i have the foreach loop in the same function?

推荐答案

中提到的意见,雷蒙德的文章,并在云锦的MSDN文章的此处

Mentioned in the comments to Raymond's article and in Yun Jin's MSDN article here that

其实,对于调试的code,JIT   延长生存期,每变量   的功能的端。

In fact, for debuggable code, JIT extends lifetime for every variable to end of the function.

因此​​您的收藏会不会被收集在调试模式下,你发现了,为什么它会被收集在释放模式。

Therefore your collection won't be collected in Debug mode as you discovered and why it will be collected in Release mode.

这篇关于还在收集对象的范围 - GC.Collect的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆