C# 垃圾收集
假设我们有:
public void foo()
{
someRefType test = new someRefType ();
test = new someRefType ();
}
垃圾收集器对第一个堆对象做什么?在新分配之前是否立即进行垃圾收集?一般机制是什么?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
谁知道?这不是确定性的。可以这样想:在具有无限内存的系统上,垃圾收集器不必做任何事情。您可能认为这是一个不好的例子,但这就是垃圾收集器为您模拟的:一个具有无限内存的系统。因为在可用内存多于程序所需内存的系统上,垃圾收集器永远不必运行。因此,您的程序无法对何时收集内存(如果有的话)做出任何假设。
所以,你的问题的答案是:我们不知道。
不。垃圾收集器不是确定性的。你不知道它什么时候会收集和释放垃圾。您不能对何时收集垃圾或何时运行终结器做出任何假设。
事实上,它不太可能如此快地收集(这会使收集发生得太频繁)。此外,在具有足够内存的系统上,垃圾收集器永远不必运行。
这是一个相当广泛的问题。但基本原理非常简单:垃圾收集器模拟具有无限内存的机器。为此,它以某种方式跟踪内存并能够确定内存何时是垃圾。当它认为合适时,由于需要模拟无限内存,它会不时收集这些垃圾并使其可再次分配。
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.
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.
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.
不,没有任何内容表明该对象会立即被收集。事实上,这不太可能。它最终会被垃圾收集器收集,但你无法知道确切的时间。
您可以通过调用 GC.Collect 来强制收集,但通常不建议这样做。
垃圾收集的具体工作原理是一个相当大的主题,但是您可以查看一些很棒的文档 阅读 MSDN。
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.Exactly how the garbage collection works is a fairly large subject, but there is great documentation you can read on MSDN.
垃圾收集有许多不同的策略,并且多年来它们变得更加复杂和高效。文献和网络上有很多关于它们的优秀资源。但我也发现有时一个不完美且丰富多彩的隐喻给了我一种直觉,可以帮助我开始。因此,请允许我尝试一下:
.NET 有一个所谓的“分代”垃圾收集器,我认为它的行为很像我自己。我让脏衣服和邮件(“C# 对象”)在客厅地板上堆满了几天(“内存”),然后我发现我再也看不到地毯了(“内存已满”) )我花了一些时间清理(“垃圾收集”)客厅(“第 0 代”),扔掉不再需要的物品(“不再可达”)并将剩余的物品移到我的卧室( “第一代”)。通常这会为我赢得一些时间,而我不需要做更多的工作。但当我的卧室被填满时,我会做类似的事情,扔掉一些物品并将其他物品移到我的地下室(“第二代”)。有时甚至地下室都填满了,然后我遇到了真正的问题,需要进行一些重大的春季大扫除(“全面收集”)。
将这个比喻应用到你的例子中,我们可能会猜测第一块垃圾(“堆对象”)只是闲置着,直到我抽出时间去捡起它(“运行第 0 代收集器”),当我愿意的时候就会发生这种情况,当地板被完全覆盖时,或者也许永远不会:-)
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. 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"). 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"). 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 :-)
要查看对象何时被删除,您可以覆盖 finalize 方法可以打印删除对象的时间和对象,如下例所示:
要强制垃圾收集器更快地释放这些对象,您可以向它们添加一个字段作为长数组,类似于
private int []memory;
并在构造函数中:memory=new int[10000000]
。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:
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;
and in the constructor:memory=new int[10000000]
.