.NET 中的垃圾收集(世代) [英] Garbage collection in .NET (generations)

查看:19
本文介绍了.NET 中的垃圾收集(世代)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了很多 .NET 性能文章,这些文章描述了 Gen1、Gen2 垃圾收集和幸存几代的对象.

I have read a lot of .NET performance articles that describe Gen1,Gen2 garbage collection and objects surviving the generations.

为什么对象会在集合中幸存下来?

Why does objects survives the collection?

什么是固定?

推荐答案

在垃圾收集器中有多个代的一个原因是避免因碎片而丢失内存.

One reason you have multiple generations in a garbage collector is to avoid losing memory to fragmentation.

每个函数调用都可能意味着创建和删除多个对象的集合,因此您的程序的内存堆往往会很快碎片化.这留下了不太有用的漏洞.结果是您的程序需要定期进行碎片整理,就像硬盘一样.这是收集期间发生的事情的一部分.

Every function call can mean the creation and deletion collection of multiple objects, and so the memory heap for your program tends to fragment very quickly. This leaves holes behind that aren't very usable. The result is that your program needs to be periodically de-fragmented, just like a hard disk. This is part of what happens during a collection.

当一个对象在一个集合中幸存下来时,它会被转移到寿命更长的一代,其理论是如果它在一个集合中幸存下来,它可能会在其他集合中幸存下来.因此,后几代人的周转率较低,也没有那么多碎片化.这意味着您的程序花费更少的时间来清理漏洞并浪费更少的内存.这也是对传统内存管理(malloc/free 或 new/delete)的改进,后者让操作系统来管理任何内存碎片.

When an object survives a collection, it is moved to a longer-lived generation on the theory that if it survived one collection it will probably survive others. Thus the later generations have less turn-over and don't fragment as much. This means your program spends less time overall juggling things around to clean up holes and wastes less memory. This is also an improvement over traditional memory management (malloc/free or new/delete), which left it up to the operating system to manage any memory fragmentation.

一个对象在集合中幸存的原因是因为在某个地方仍然在范围内"并且持有对该对象的引用.有几种方法可以导致这种情况发生,然后忘记引用,因此可能会在托管代码中泄漏"内存.

The reason an object survives collection is because there is something somewhere that is still "in scope" and holds a reference to that object. There are a few ways you can cause this to happen and then forget about the reference, so it is possible to "leak" memory in managed code.

有时人们很想调用 GC.Collect() 来让垃圾收集器清理一些东西.也许他们发现他们有泄漏,或者认为内存变得过度碎片化.你应该抵制这些冲动.虽然 .Net 中的垃圾收集并不完美,但它是否非常好,而且几乎可以肯定它在清理内存方面比你要好得多.奇怪的是,如果一个对象可以而且应该被收集,它就会被收集.请记住,调用 GC.Collect() 实际上可以通过帮助垃圾收集器将对象向上移动到更高的代而使事情变得更糟,从而使它们保持更长的时间.

Sometimes people are tempted to call GC.Collect() in an effort to get the garbage collector to clean something up. Perhaps they've discovered they have a leak, or think memory is becoming over-fragmented. You should resist those urges. While garbage collection in .Net is not perfect, is it very good, and it's almost certainly much better at cleaning up memory than you are. Odds are that if an object can and should be collected, it will be. Remember that calling GC.Collect() can actually make things worse by helping the garbage collector move objects up to a higher generation, and thus keeping them around for longer than they otherwise would be.

相反,如果您怀疑自己有泄漏,请查看您自己的代码以查找可能包含对许多其他项目的引用的全局或静态变量.你应该调用 GC.Collect() 的唯一时间是当你有关于垃圾收集器不可用的程序性质的信息时,这是非常罕见的,因为 GC 知道你的每个引用'已创建.

Instead, if you suspect you have a leak, look to your own code for something like a global or static variable that might hold a reference to a lot of other items. The only time you should call GC.Collect() is when you have information about the nature of the program that is not available to the garbage collector, and that's pretty rare as the GC knows every reference you've created.

固定"用于需要将对象传递给非托管库的情况.垃圾收集器可以移动对象在内存中的物理位置,因此您需要将其固定"在一个地方,否则非托管库使用的指针可能会变得无效.无法收集固定对象,因此您不应将对象固定超过必要的时间.

"Pinning" is for when you need to pass an object to an unmanaged library. The garbage collector can move an object's physical location in memory, and so you need to "pin" it in one place or the pointer used by the unmanaged library could become invalid. A pinned object cannot be collected, and so you shouldn't pin an object for any longer than necessary.

这篇关于.NET 中的垃圾收集(世代)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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