C# 垃圾回收

Posted

技术标签:

【中文标题】C# 垃圾回收【英文标题】:C# Garbage collection 【发布时间】:2011-11-29 03:03:53 【问题描述】:

假设我们有:

public void foo()

   someRefType test = new someRefType ();
   test = new someRefType ();

垃圾收集器如何处理第一个堆对象?是否在新分配之前立即收集垃圾?一般机制是什么?

【问题讨论】:

你试过这个(google.com/search?q=how+c%23+garbage+collection+works)吗?真的,这会给你一堆高质量的解释,就在列表的顶部。 【参考方案1】:

垃圾收集器如何处理第一个堆对象?

谁知道?这不是确定性的。可以这样想:在具有无限内存的系统上,垃圾收集器没有任何事情。你可能认为这是一个不好的例子,但这就是垃圾收集器为你模拟的:一个具有无限内存的系统。因为在可用内存比程序所需的足够多的系统上,垃圾收集器永远必须运行。因此,您的程序无法对何时收集内存(如果有的话)做出任何假设。

所以,您的问题的答案是:我们不知道。

在新分配之前是否立即收集垃圾?

没有。垃圾收集器不是确定性的。你不知道它什么时候会收集和释放垃圾。您不能对何时收集垃圾或何时运行终结器做出任何假设。

事实上,它不太可能被这么快收集(这会使收集过于频繁)。此外,在具有足够内存的系统上,垃圾收集器从不 必须运行。

一般机制是什么?

这是一个相当广泛的问题。但其基本原理非常简单:垃圾收集器模拟一台内存无限的机器。为此,它以某种方式跟踪内存并能够确定内存何时是垃圾。当它认为合适时,由于需要模拟无限内存,它会不时收集这些垃圾并使其再次可用于分配。

【讨论】:

或者更准确地说“我们不知道”。【参考方案2】:

不,没有任何内容表明该对象被立即收集。事实上,这不太可能。它最终会被垃圾收集器收集,但你无法确切知道何时。

您可以通过调用 GC.Collect 来强制收集,但通常不建议这样做。

垃圾回收的具体工作原理是一个相当大的主题,但是您可以read on MSDN 找到很好的文档。

【讨论】:

【参考方案3】:

有许多不同的垃圾收集策略,这些年来它们变得更加复杂和高效。文献和网络上有很多关于它们的优秀资源。但我也发现有时一个不完美且色彩丰富的比喻给了我一种直觉,帮助我开始。所以请允许我试一试:

.NET 有一个所谓的“分代”垃圾收集器,我认为它的行为就像我自己一样。我让脏衣服和邮件(“C# 对象”)在我的客厅地板上堆积了几天(“内存”),当我发现我再也看不到地毯时(“内存已满” )我花了一些时间清理(“垃圾收集”)起居室(“0代”),扔掉不再需要的物品(“不再可用”)并将剩余的物品移到我的卧室( “第一代”)。很多时候,这为我争取了一些时间,我不需要再做任何工作了。但是当我的卧室填满时,我会做类似的事情,扔掉一些物品并将其他物品移到我的地下室(“第 2 代”)。有时甚至地下室也会被填满,然后我遇到了真正的问题,需要进行一些大的春季大扫除(“完整收集”)。

将这个比喻应用到您的示例中,我们可能会猜测第一块垃圾(“堆对象”)只是闲置,直到我有时间捡起它(“运行第 0 代收集器”),当我感觉喜欢它,当地板被完全覆盖时,或者永远不会:-)

【讨论】:

【参考方案4】:

要查看对象何时被删除,您可以覆盖类中的finalize 方法以打印何时以及哪些对象被删除,如下面的示例所示:

class MyClass

    private int _id;

    public MyClass(int id)
    
        _id = id;
    

    ~MyClass()
    
        Console.WriteLine("Object " + _id + " deleted at " + DateTime.Now + " .");
    


class Program

    static void Main(string[] args)
    
        MyClass p1 = new MyClass(1);
        p1 = new MyClass(2);

        Console.ReadKey();
    

要强制垃圾收集器更快地释放这些对象,您可以将一个字段作为长数组添加到它们,例如 private int []memory; 并在构造函数中:memory=new int[10000000]

【讨论】:

以上是关于C# 垃圾回收的主要内容,如果未能解决你的问题,请参考以下文章

浅析C#中的托管非托管堆栈与垃圾回收

C# 垃圾回收

java垃圾是怎么回收的,回收算法

C# LazyCache 并发字典垃圾回收

C# 垃圾回收机制(GC) 的概述 资源清理 内存管理

C# 垃圾回收机制(GC) 的概述 资源清理 内存管理