.net 垃圾收集中的世代是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2257563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 13:54:24  来源:igfitidea点击:

What are the Generations in Garbage Collection?

.netgarbage-collection

提问by Adriaan Stander

I don't understand what "generations" are in the context of Garbage Collection. Can someone explain in simple terms?

我不明白垃圾收集上下文中的“世代”是什么。有人可以用简单的术语解释一下吗?

回答by Adriaan Stander

From Understanding Garbage Collection in .NET

了解 .NET 中的垃圾收集

Generations

A generational garbage collector collects the short-lived objects more frequently than the longer lived ones. Short-lived objects are stored in the first generation, generation 0. The longer-lived objects are pushed into the higher generations, 1 or 2. The garbage collector works more frequently in the lower generations than in the higher ones.

When an object is first created, it is put into generation 0. When the generation 0 is filled up, the garbage collector is invoked. The objects that survive the garbage collection in the first generation are promoted onto the next higher generation, generation 1. The objects that survive garbage collection in generation 1 are promoted onto the next and the highest generation, generation 2. This algorithm works efficiently for garbage collection of objects, as it is fast. Note that generation 2 is the highest generation that is supported by the garbage collector.

几代人

分代垃圾收集器比长寿命对象更频繁地收集短寿命对象。生命周期较短的对象存储在第一代,即 0 代。生命周期较长的对象被推入较高的代,即 1 或 2。垃圾收集器在较低的代中比在较高的代中更频繁地工作。

当一个对象第一次被创建时,它被放入第 0 代。当第 0 代被填满时,垃圾收集器被调用。在第一代垃圾收集中幸存下来的对象被提升到下一个更高的一代,即第 1 代。在第 1 代垃圾收集中幸存下来的对象被提升到下一个最高代,即第 2 代。该算法对垃圾有效对象的集合,因为它很快。请注意,第 2 代是垃圾收集器支持的最高代。

Garbage Collection in .NET

.NET 中的垃圾收集

Generations

While memory allocation on the managed heap is fast, GC itself may take some time. With this in mind several optimisations have been made to improve performance. The GC supports the concept of generations, based on the assumption that the longer an object has been on the heap, the longer it will probably stay there. When an object is allocated on the heap it belongs in generation 0. Each garbage collection that that object survives increases its generation by 1 (currently the highest supported generation is 2). Obviously it's faster to search through, and garbage collect a subset of all objects on the heap, so the GC has the option of collecting only generation 0, 1 or 2 objects (or whatever combination it chooses until it has sufficient memory). Even while collecting only younger objects the GC can also determine if old objects have references to new objects to ensure that it doesn't inadvertently ignore in-use objects.

几代人

虽然托管堆上的内存分配很快,但 GC 本身可能需要一些时间。考虑到这一点,我们进行了多项优化以提高性能。GC 支持代的概念,基于这样一个假设,即对象在堆上的时间越长,它可能在那里停留的时间就越长。当一个对象在堆上分配时,它属于第 0 代。该对象幸存下来的每个垃圾收集将其代数增加 1(当前支持的最高代数是 2)。显然,搜索和垃圾收集堆上所有对象的子集会更快,因此 GC 可以选择只收集第 0、1 或 2 代对象(或它选择的任何组合,直到它有足够的内存)。

回答by duffymo

There's a nice description in "Pro C# 2008":

“Pro C# 2008”中有一个很好的描述:

  1. Generation 0 identifies a newly created object that has never been marked for collection
  2. Generation 1 identifies an object that has survived a GC (marked for collection but not removed because there was sufficient heap space)
  3. Generation 2 identifies an object that has survived more than one sweep of the GC.
  1. 第 0 代标识从未标记为收集的新创建对象
  2. 第 1 代标识在 GC 中幸存下来的对象(标记为收集但未删除,因为有足够的堆空间)
  3. 第 2 代标识在 GC 的多次扫描中幸存下来的对象。

回答by Deepak Mishra

My first blog, Generations of Garbage Allocation, answers your question:

我的第一个博客, 垃圾分配的代际,回答了你的问题:

The CLR's Garbage collector (GC) is a generational garbage collector, also known as ephermal garbage collector.

It has three generations:

Generation 0 :

It contains all newly constructed object which are never examined by GC.

Generation 1:

The CLR, when initializes, selects a budget size in kb for generation 0 . If the creation of an object causes the generation 0 to surpass its budget, garbage collection is started. The objects which are not collected in Generation 0 are moved to Generation 1 and Generation 0 is emptied. Let's say the budget of Generation 0 is equal to size of 5 objects. So generation 0 would look like below before creation of object 6:

enter image description here

After creation of object 6, garbage allocation gets started which deallocates the garbage objects 1, 3 and 5 and moves 2 and 4 adjacent to each other in Generation 1.

enter image description here

The budget size of generation 1 is also selected by CLR upon initialization. Creation of object 11 causes the GC to start again which may move some more objects to generation 1.

enter image description here

Generation 1 is ignored for Garbage Collection until it reaches its budget size for Garbage collection, which improves the performance of GC.

Generation 2:

Over the several generation 0 collection, generation 1 may surpass it's budget limit which cause GC to collect the Garbage from both generations. In this case, generation 1 survivors are promoted to generation 2, generation 0 survivors are promoted to generation 1, and generation 0 is empty.

Let's say allocation object 21 cause Garbage collection and generation 1 budget have been reached. enter image description here

So heap would look like below with the object that survived in Generation 1 promoted to generation 2.

enter image description here

So basically Generation GC assumes that newer objects have more probability to collected.

We know that CLR selects budgets for all three generations but it can modify them as GC is a self-tuning collector. If GC sees that there are very few surviving objects after collecting generation 0, it might decide to reduce the budget of generation 0, so that lesser work is done. On the other hand, if GC collects generation 0 and sees that there are a lot of surviving objects, not a lot of memory was reclaimed in the garbage collection. In this case, the garbage collector will grow generation 0's budget. The GC also modifies the budgets of generation 1 and generation 2 accordingly.

CLR 的垃圾收集器 (GC) 是一种分代垃圾收集器,也称为临时垃圾收集器。

它分为三代:

第 0 代:

它包含所有新构造的对象,这些对象从未被 GC 检查过。

第 1 代:

CLR 在初始化时为第 0 代选择一个以 kb 为单位的预算大小。如果对象的创建导致第 0 代超出其预算,则会启动垃圾收集。没有在第 0 代中收集的对象被移动到第 1 代并且第 0 代被清空。假设第 0 代的预算等于 5 个对象的大小。因此,在创建对象 6 之前,第 0 代将如下所示:

在此处输入图片说明

创建对象 6 后,开始垃圾分配,释放垃圾对象 1、3 和 5,并在第 1 代中移动彼此相邻的 2 和 4。

在此处输入图片说明

第 1 代的预算大小也由 CLR 在初始化时选择。创建对象 11 会导致 GC 再次启动,这可能会将更多对象移动到第 1 代。

在此处输入图片说明

垃圾收集会忽略第 1 代,直到它达到垃圾收集的预算大小,从而提高 GC 的性能。

第 2 代:

在几代 0 收集中,第 1 代可能会超出其预算限制,导致 GC 收集来自两代的垃圾。在这种情况下,第 1 代幸存者被提升到第 2 代,第 0 代幸存者被提升到第 1 代,而第 0 代是空的。

假设分配对象 21 导致垃圾收集和第 1 代预算已达到。 在此处输入图片说明

所以堆看起来像下面这样,在第 1 代中幸存下来的对象被提升到第 2 代。

在此处输入图片说明

所以基本上 Generation GC 假设较新的对象更有可能被收集。

我们知道 CLR 为所有三代选择预算,但它可以修改它们,因为 GC 是一个自调整收集器。如果 GC 发现在收集第 0 代后幸存的对象很少,它可能会决定减少第 0 代的预算,以便完成较少的工作。另一方面,如果 GC 收集第 0 代并看到有很多幸存的对象,则垃圾收集中并没有回收大量内存。在这种情况下,垃圾收集器将增加第 0 代的预算。GC 还相应地修改了第 1 代和第 2 代的预算。