问题描述
虽然我确实理解使用这个函数的严重影响(或者至少我是这么认为的),但我不明白为什么它会成为受人尊敬的程序员永远不会使用的东西之一,即使是那些不使用的人甚至不知道它是做什么用的.
Although I do understand the serious implications of playing with this function (or at least that's what I think), I fail to see why it's becoming one of these things that respectable programmers wouldn't ever use, even those who don't even know what it is for.
假设我正在开发一个应用程序,其中内存使用量因用户的操作而异.应用程序生命周期可以分为两个主要阶段:编辑和实时处理.在编辑阶段,假设创建了数十亿甚至数万亿个对象;其中有些很小,有些没有,有些可能有终结器,有些可能没有,假设它们的生命周期从几毫秒到几个小时不等.接下来,用户决定切换到实时阶段.在这一点上,假设性能起着根本性的作用,程序流程中最轻微的改变都可能带来灾难性的后果.然后通过使用对象池等将对象创建减少到最低限度,但随后 GC 意外地响起并将其全部扔掉,然后有人死了.
Let's say I'm developing an application where memory usage varies extremely depending on what the user is doing. The application life cycle can be divided into two main stages: editing and real-time processing. During the editing stage, suppose that billions or even trillions of objects are created; some of them small and some of them not, some may have finalizers and some may not, and suppose their lifetimes vary from a very few milliseconds to long hours. Next, the user decides to switch to the real-time stage. At this point, suppose that performance plays a fundamental role and the slightest alteration in the program's flow could bring catastrophic consequences. Object creation is then reduced to the minimum possible by using object pools and the such but then, the GC chimes in unexpectedly and throws it all away, and someone dies.
问题:在这种情况下,在进入第二阶段之前调用GC.Collect()是不是很明智?
The question: In this case, wouldn't it be wise to call GC.Collect() before entering the second stage?
毕竟,这两个阶段在时间上永远不会重叠,GC 可以收集的所有优化和统计信息在这里都没什么用......
After all, these two stages never overlap in time with each other and all the optimization and statistics the GC could have gathered would be of little use here...
注意:正如你们中的一些人所指出的,.NET 可能不是此类应用程序的最佳平台,但这超出了本问题的范围.目的是阐明 GC.Collect() 调用是否可以改善应用程序的整体行为/性能.我们都同意,在这种情况下你会做这样的事情是极其罕见的,但话又说回来,GC 尝试猜测并且在大多数情况下做得很好,但它仍然是猜测.
Note: As some of you have pointed out, .NET might not be the best platform for an application like this, but that's beyond the scope of this question. The intent is to clarify whether a GC.Collect() call can improve an application's overall behaviour/performance or not. We all agree that the circumstances under which you would do such a thing are extremely rare but then again, the GC tries to guess and does it perfectly well most of the time, but it's still about guessing.
谢谢.
推荐答案
规则 #1
不要.
这真的是最重要的规则.公平地说,大多数GC.Collect() 的用法是个坏主意我详细介绍了原来的帖子所以我不会重复这一切都在这里.那么让我们继续...
This is really the most importantrule. It's fair to say that mostusages of GC.Collect() are a bad ideaand I went into that in some detail inthe orginal posting so I won't repeatall that here. So let's move on to...
规则#2
考虑调用 GC.Collect() 如果有非经常性事件刚刚发生并且这个事件极有可能造成了很多旧物死.
Consider calling GC.Collect() if somenon-recurring event has just happenedand this event is highly likely tohave caused a lot of old objects todie.
一个典型的例子是如果你编写一个客户端应用程序和你显示一个非常大而复杂的具有大量关联数据的表单用它.您的用户刚刚可能与此表单交互创建一些大对象...东西像 XML 文档或大型数据集或两个.当表单关闭这些对象死了,所以 GC.Collect()将回收相关的内存与他们...
A classic example of this is if you'rewriting a client application and youdisplay a very large and complicatedform that has a lot of data associatedwith it. Your user has justinteracted with this form potentiallycreating some large objects... thingslike XML documents, or a large DataSetor two. When the form closes theseobjects are dead and so GC.Collect()will reclaim the memory associatedwith them...
所以听起来这种情况可能属于规则 #2,您知道有一段时间许多旧对象已经死亡,并且不会再次发生.不过,别忘了Rico的离别词.
So it sounds like this situation may fall under Rule #2, you know that there's a moment in time where a lot of old objects have died, and it's non-recurring. However, don't forget Rico's parting words.
规则 #1 应该胜过规则 #2有力的证据.
测量,测量,再测量.
这篇关于使用 GC.Collect() 有什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!