C# GC.Collect()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1149197/
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-08-06 09:24:32  来源:igfitidea点击:

GC.Collect()

c#.netvb.netgarbage-collection

提问by devoured elysium

Ok, I've read a couple of topics about it, but here it goes. Let's imagine I have an application where basically every now and then I will click on a button, a lot of things will happen for a couple of minutes, and then it'll stay idle possible for another hour, or maybe just 1 minute. Wouldn't just after that whole ended a good situation to call GC.Collect? I mean, I do know that just at that moment I will not being using my application, and GC cannot guess it.

好的,我已经阅读了一些关于它的主题,但它就在这里。让我们假设我有一个应用程序,基本上我会时不时地单击一个按钮,很多事情会发生几分钟,然后它可能会再闲置一个小时,或者可能只有 1 分钟。不是在整个结束之后调用 GC.Collect 的好情况吗?我的意思是,我确实知道在那一刻我不会使用我的应用程序,GC 无法猜测。

采纳答案by mfawzymkh

I can see that several people have gone extreme about not recommending to call GC.Collect.

我可以看到有几个人在不建议调用 GC.Collect 方面变得极端。

GC.Collect is there for a reason, here are my recommendation of when and why to call GC.Collect.

GC.Collect 的存在是有原因的,以下是我对何时以及为何调用 GC.Collect 的建议。

  1. In General, don't worry about calling it, GC tunes itself very well and will do the right thing.

  2. Sometimes, you end up in situation where you know for sure that this is the right time to call it, the situation you described above is exactly the right time to call it, in fact Asp.Net calls GC.Collect at certain points that are similar to what you described.

  3. The GC is smart about calling GC.Collect, if you called GC.Collect, the GC can override your decision and still doesn't collect ( you have to set a flag when you call GC.Collect to choose this behavior), this is the recommended way of calling GC.Collect, since you are still letting the GC decides if it is a good time to collect.

  4. Don't take my recommendation is a general statement for calling GC.Collect, you should always avoid calling it, unless you REALLY sure you need to call it, situation like the one you described is exactly why GC.Collect is there.

  5. The benefit you will get from calling it is freeing the garbage quickly, generally you will care about this situation if

    1. You are in low memory situation and want to be eager about collection, if you are in low memory situation, the GC will be aggressive anyway and will kick in automatically if the memory pressure is high on the machine
    2. If you want to avoid getting in low memory situation and you want to collect eagerly.
  1. 一般来说,不要担心调用它,GC 会很好地调整自己,并且会做正确的事情。

  2. 有时,您最终会遇到这样的情况:您确定这是调用它的正确时间,上面描述的情况正是调用它的正确时间,实际上 Asp.Net 在某些点调用 GC.Collect和你描述的类似。

  3. GC 很聪明地调用 GC.Collect,如果你调用 GC.Collect,GC 可以覆盖你的决定并且仍然不收集(你必须在调用 GC.Collect 时设置一个标志来选择这个行为),这是调用 GC.Collect 的推荐方式,因为您仍在让 GC 决定是否是收集的好时机。

  4. 不要接受我的建议是调用 GC.Collect 的一般声明,您应该始终避免调用它,除非您真的确定需要调用它,像您描述的情况正是 GC.Collect 存在的原因。

  5. 调用它的好处是快速释放垃圾,通常你会关心这种情况,如果

    1. 您处于内存不足的情况并且想要急于收集,如果您处于内存不足的情况下,无论如何GC都会很积极,并且如果机器上的内存压力很高,则会自动启动
    2. 如果您想避免陷入低内存情况并且您想急切地收集。

Hope this helps.
Thanks

希望这可以帮助。
谢谢

回答by Randolpho

There's almost never a good reason to call GC.Collect().

几乎从来没有一个很好的理由调用GC.Collect()

In your case, there is absolutely no reason to call it. If you're idle for an hour, the GC willdo its collections.

在您的情况下,绝对没有理由调用它。如果您闲置了一个小时,GC进行收集。

回答by Steven Lyons

It's almost always a premature optimization to worry about calling GC.Collect before you've prototyped or built the application and tested its performance. The GC is usually very good at collecting memory at the appropriate times. It will certainly run a collection while your application is idle, especially if there is memory pressure in the system.

在您制作原型或构建应用程序并测试其性能之前,担心调用 GC.Collect 几乎总是一种过早的优化。GC 通常非常擅长在适当的时间收集内存。它肯定会在您的应用程序空闲时运行一个集合,尤其是在系统内存压力较大的情况下。

It is much more important that you follow good generational GC allocation practices (small objects, short usage, etc.) and you will likely get the performance characteristics you are wanting. If you still don't have the performance you need, after profiling and good design you might think about GC.Collect as a solution.

遵循良好的分代 GC 分配实践(小对象、短期使用等)更为重要,您可能会获得所需的性能特征。如果您仍然没有所需的性能,在分析和良好的设计之后,您可能会考虑将 GC.Collect 作为解决方案。

回答by Sam Harwell

To know when to call GC.Collect(), you'd need to know details of the specific collector involved with the runtime along with detailed information about a weak point that you can solve with the collection.

要知道何时调用GC.Collect(),您需要了解与运行时相关的特定收集器的详细信息以及有关您可以使用该集合解决的弱点的详细信息。

In other words, if you really know when you need to call GC.Collect(), and it's not something you'd done poorly in other code, then you probably work for CLR Internalsand can just fix the problem.

换句话说,如果您真的知道什么时候需要调用GC.Collect(),并且这不是您在其他代码中做得不好的事情,那么您可能为CLR Internals工作并且可以解决问题。

回答by Senthil Kumar

I'm hoping you're aware that calling GC.Collect doesn't cause more (or less) objects to be collected.

我希望您知道调用 GC.Collect 不会导致收集更多(或更少)的对象。

If you're trying to optimize for time, do you know the time GC takes to collect objects in your application? On desktop operating systems (XP, Vista etc..), the CLR uses a concurrent GC, and it can run without suspending all threads in the application for the duration of the collection.

如果您正在尝试优化时间,您是否知道 GC 在您的应用程序中收集对象所花费的时间?在桌面操作系统(XP、Vista 等)上,CLR 使用并发 GC,它可以在不暂停应用程序中的所有线程的情况下在收集期间运行。

Explicitly calling GC.Collect is not recommended because

不推荐显式调用 GC.Collect 因为

  1. It throws the CLR GC Tuning algorithm out of gear. The tuner determines when to trigger a GC automatically, and forcing a manual GC messes with its calculations.

  2. By forcing a collection manually, you can end up promoting objects up a generation - objects which might have been collected in the next GC ( if they were "orphaned" before the GC decided to kick in).

  1. 它使 CLR GC 调优算法失灵。调谐器决定何时自动触发 GC,强制手动 GC 会干扰其计算。

  2. 通过手动强制收集,您最终可以将对象提升一代 - 可能已在下一次 GC 中收集的对象(如果它们在 GC 决定启动之前被“孤立”)。

You might find it interesting that .NET 4.0, a GC notification mechanismhas been introduced for these kinds of scenarios.

您可能会发现 .NET 4.0 很有趣,它为这些类型的场景引入了GC 通知机制

回答by Bill Crim

Normally the GC is only called if you attempt to allocate new memory. If you don't run out of memory, you obtain 0% performance improvement from calling the GC. You have to have a pretty insanely resource intensive application to even come close to the limits of RAM on todays computers.

通常,只有在您尝试分配新内存时才会调用 GC。如果您没有耗尽内存,则通过调用 GC 可以获得 0% 的性能提升。你必须有一个非常疯狂的资源密集型应用程序才能接近当今计算机上的 RAM 限制。

If you program has lots of external resources(like files or COM/DCOM references), you potentially would want to call the GC.

如果您的程序有大量外部资源(如文件或 COM/DCOM 引用),您可能需要调用 GC。

If calling the GC will give you peace of mind, then go ahead. It likely won't help, but it certainly wouldn't hurt.

如果调用 GC 会让您安心,那么请继续。它可能不会有帮助,但肯定不会受到伤害。

回答by Arsen Mkrtchyan

Yea as mentioned in other posts GC know when to start collection better than you, the factor that no buttons are clicked in your application doesn't mean that it is the time to start cleaning, GC is doing some kind of lockings when moving the objects, so this may cause low performance if you will abuse GC.Collect

是的,正如其他帖子中提到的,GC 比您更了解何时开始收集,在您的应用程序中没有单击按钮的因素并不意味着是时候开始清理了,GC 在移动对象时会进行某种锁定,因此如果您滥用 GC.Collect,这可能会导致性能下降