简体   繁体   English

C# 垃圾收集

[英]C# Garbage collection

Say we have:假设我们有:

public void foo()
{
   someRefType test = new someRefType ();
   test = new someRefType ();
}

What does the garbage collector do with the first heap object?垃圾收集器如何处理第一个堆对象? Is it immediately garbage collected before the new assignment?是否在新分配之前立即进行垃圾回收? What is the general mechanism?一般机制是什么?

What does the garbage collector do with the first heap object?垃圾收集器如何处理第一个堆对象?

Who knows?谁知道? It's not deterministic.这不是确定性的。 Think of it like this: on a system with infinite memory, the garbage collector doesn't have to do anything .想想看这样的:用无限的内存的系统上,垃圾回收器不会任何事情 And you might think that's a bad example, but that's what the garbage collector is simulating for you: a system with infinite memory.您可能认为这是一个不好的例子,但这就是垃圾收集器为您模拟的:一个具有无限内存的系统。 Because on a system with sufficiently more memory available than required by your program, the garbage collector never has to run.因为在可用内存多于程序所需内存的系统上,垃圾收集器永远不必运行。 Consequently, your program can not make any assumptions about when memory will (if ever) be collected.因此,您的程序无法对何时(如果有的话)收集内存做出任何假设。

So, the answer to your question is: we don't know.所以,你的问题的答案是:我们不知道。

Is it immediately garbage collected before the new assignment?是否在新分配之前立即进行垃圾回收?

No. The garbage collector is not deterministic.不。垃圾收集器不是确定性的。 You have no idea when it will collect and release garbage.你不知道它什么时候会收集和释放垃圾。 You can not make any assumptions about when garbage will be collected or when finalizers will run.您不能对何时收集垃圾或何时运行终结器做出任何假设。

In fact, it's very unlikely it's collected so quickly (that would make collections happen too frequently).事实上,它不太可能被收集得如此之快(这会使收集发生得太频繁)。 Additionally, on a system with sufficient memory, the garbage collector never has to run.此外,在具有足够内存的系统上,垃圾收集器永远不必运行。

What is the general mechanism?一般机制是什么?

That's a fairly broad question.这是一个相当广泛的问题。 But the underlying principle is very simple: a garbage collector simulates a machine with infinite memory.但其基本原理非常简单:垃圾收集器模拟了一台具有无限内存的机器。 To do this, it somehow keeps track of memory and is able to determine when memory is garbage.为此,它会以某种方式跟踪内存并能够确定内存何时是垃圾。 When it sees fit, due to its need to simulate infinite memory, it will from time to time collect this garbage and make it available for allocation again.当它认为合适时,由于需要模拟无限内存,它会不时收集这些垃圾并使其再次可供分配。

No, there is nothing that says that the object is immediately collected.不,没有任何内容表明该对象会立即被收集。 In fact, it is quite unlikely that it is.事实上,这是不太可能的。 It will be collected eventually by the garbage collector, but you can't know exactly when.垃圾收集器最终会收集它,但您无法确切知道何时。

You can force a collection by calling GC.Collect , although this is normally not recommended.您可以通过调用GC.Collect强制收集,尽管通常不建议这样做。

Exactly how the garbage collection works is a fairly large subject, but there is great documentation you can read on MSDN .垃圾收集的确切工作原理是一个相当大的主题,但您可以在 MSDN 上阅读大量文档。

There are numerous different strategies for garbage collection and they have gotten more sophisticated and more efficient over the years.有许多不同的垃圾收集策略,这些年来它们变得更加复杂和高效。 There's lots of excellent resources in the literature and on the web that talk about them.文献和网络上有很多关于它们的优秀资源。 But I also find sometimes an imperfect and colorful metaphor gives me an intuition that helps me get started.但我也发现有时一个不完美且色彩丰富的比喻会给我一种帮助我开始的直觉。 So allow me to try:所以请允许我尝试:

.NET has a so-called "generational" garbage collector and I think of it as behaving I lot like I do myself. .NET 有一个所谓的“分代”垃圾收集器,我认为它的行为与我自己的行为非常相似。 I let dirty clothes and mail ("C# objects") pile up all over my living room floor ("memory") over a period of several days and when I find that I can't see the carpet any more ("memory full") I spend some time cleaning up ("garbage collecting") the living room ("generation 0"), throwing away the objects that aren't needed any more ("no longer reachable") and moving the remaining ones to my bedroom ("generation 1").在几天的时间里,我让脏衣服和邮件(“C# 对象”)堆积在我客厅的地板上(“内存”),当我发现我再也看不到地毯时(“内存已满”) )我花了一些时间清理(“垃圾收集”)起居室(“第 0 代”),扔掉不再需要的物品(“不再可及”),并将剩余的物品移到我的卧室( “第 1 代”)。 Quite often this buys me some time and I don't need to do any more work.很多时候,这为我赢得了一些时间,我不需要再做任何工作了。 But when my bedroom fills up I do something similar, throwing away some objects and moving the others to my basement ("generation 2").但是当我的卧室填满时,我会做类似的事情,扔掉一些物品并将其他物品移到我的地下室(“第 2 代”)。 Occasionally even the basement fills up and then I have I real problem and need to do some major spring cleaning ("full collection").有时甚至地下室都填满了,然后我遇到了真正的问题,需要做一些主要的春季大扫除(“全面收集”)。

Applying this metaphor to your example, we might guess that the first piece of trash ("heap object") just sits around until I get around to picking it up ("run the generation 0 collector") which happens when I feel like it, when the floor gets completely covered, or maybe never :-)将这个比喻应用到您的示例中,我们可能会猜测第一块垃圾(“堆对象”)就在附近,直到我有时间捡起它(“运行第 0 代收集器”),当我喜欢它时就会发生这种情况,当地板被完全覆盖时,或者永远不会:-)

To see when the objects are being deleted, you can override the finalize method in your class to print when and what objects are being deleted, like in this sample below:要查看对象何时被删除,您可以覆盖类中的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();
    }
}

To force the garbage collector to free this objects faster, you could add a field to them as a long array, something like private int []memory;为了强制垃圾收集器更快地释放这些对象,您可以将一个字段作为长数组添加到它们中,例如private int []memory; and in the constructor: memory=new int[10000000] .并在构造函数中: memory=new int[10000000]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM