触发外部.NET垃圾回收

27

有没有办法从另一个进程或从WinDBG内部触发.NET进程中的垃圾回收呢?

有托管调试助手可在跨越本机/托管代码边界时强制进行垃圾回收,AQTime似乎有一个按钮可以执行此操作,但我找不到任何关于如何执行此操作的文档。


可能是从命令行运行垃圾收集器?的重复问题。 - Eric Boumendil
4个回答

21

另一个问题 中有答案:

基本上,使用 PerfView

PerfView.exe ForceGC [ProcessName | Process ID] /AcceptEULA

它不适用于生产环境。


1
最新版本2.0.7也需要在其上加上/AcceptEula开关。 - bergmeister

10

好的...有立即窗口。如果你有附加到进程的奢侈条件,我认为你可以在立即窗口中手动调用GC.Collect。

更大的问题是:为什么要手动引发GC.Collect?这是一种不良习惯,并表明存在更大的设计问题。


1
这不是我经常做的事情,也不是我的习惯 :-)。我们偶尔会遇到内存使用问题;当出现这些问题时,GC会频繁进行垃圾回收。在调查时,为了加快速度,最好使用简化的数据集,但这些数据集不能以同样的方式压力测试GC。... - Ian G
[续...] 在处理较小的数据集时,有时候有用的信息之一是GC可能可以回收多少内存。如果只有一个特定点需要调整代码以强制回收,但偶尔使用更加临时的方法会更方便。 - Ian G
我同意,我也使用GC.Collect来达到这个目的,通常在观察perfmon时看看“我能得到什么”。 做得好,看起来你站在GC争论的正确一边 :) - David Hill

3

John Cocktoastan提出在Visual Studio中使用GC.Collect是最佳选择,如果有的话。

我仍然找不到在WinDBG下实际进行收集的替代方案,但是退一步考虑“可回收内存量有多少?”(请参见我对John答案的评论),我认为可以通过使用脚本(PowerDBG?)搜索一些组合以查找非根处理程序并总结使用的空间(基本上使用调试器模拟GC将要执行的算法)。 但是自从想到这个想法以来,我就没有遇到过这些错误,因此还没有尝试编写代码来执行它。


0
如果您通过远程公开一个函数/对象,那将非常容易实现。

我感兴趣的应用程序目前不支持远程操作,仅为此添加远程操作也是不可行的。 - Ian G
为什么一个单独暴露的可远程对象是不可行的?你可以用不到20行代码实现它。这里有一个小例子:http://xacc.svn.sourceforge.net/viewvc/xacc/xacc/Configuration/KickStart.cs?view=markup - leppie
1
因为这是一个本地的C++应用程序,只通过COM访问.NET,虽然有很多C#代码,但可以钩取的部分非常少。还有一些非技术原因。 - Ian G

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接