【问题标题】:Does garbage collection run during debug?垃圾收集是否在调试期间运行?
【发布时间】:2019-03-15 06:35:50
【问题描述】:

我有一个程序可以打开一个 Excel COM 对象,做一些事情,然后关闭它。然后我想在它关闭后移动那个文件。如果我在没有断点的情况下运行程序,这很好。但是,如果我在调试模式之前进入某些东西,我会尝试移动文件,我得到一个 IOException:“该进程无法访问该文件,因为它正在被另一个进程使用。”

那么交易是什么?当一个程序被允许全速运行而不是当我单步执行它时,垃圾收集的性能是否更好?单步执行我的代码不仅仅是非常缓慢地运行它吗?调试模式还有其他后果吗?仅仅因为我在调试而不运行exe而遇到的其他错误?

【问题讨论】:

  • 您是如何处理 Excel 对象的?如果您在 VS 调试器停止后看到错误并且您已让代码运行 COM 对象处理,那么您可能有一个有效点。

标签: c# garbage-collection


【解决方案1】:

当不在调试器中运行时,垃圾收集的优化方式不同,是的。特别是,CLR 可以检测到变量不会用于方法的其余部分,并将其不再视为 GC 根。在调试器中,作用域中的变量在整个方法中充当 GC 根,因此您仍然可以使用调试器检查值。

但是,这应该很少成为问题 - 只有在终结器实际执行一些清理并且您明确及时整理(例如,使用using 语句)您通常不会注意到差异。

【讨论】:

  • 所以我可以期望我的程序在不在调试器中运行时运行得更快?调试器故意占用更多内存......所以我可以调试。正确的?无论哪种方式,我都不明白为什么断点的位置会影响对象是否可用。如果我按 F5 并用零断点测试我的代码并且从不“进入”它,调试器的执行是否仍然与常规构建不同?
  • @Brad:“快得多”是相当主观的。老实说,目前尚不清楚您在做什么——但使用 F5 运行仍在使用调试器; Ctrl-F5 没有。这不是您正在运行哪个build 的问题,而是您正在运行它的如何。 (您可以在调试器中运行发布版本,或不在调试器中运行调试版本。)
  • 因此,如果我不在调试器中运行调试构建,是否还会执行像 Debug.Print() 这样的行?它们在发布版本中被忽略了吗?
【解决方案2】:

为了记录,我也遇到过几次。我发现在调试模式下测试调用本机端代码的终结器时这很有效:

((Action)()=>{
   // Do your stuff in here ...
})();

GC.Collect();
GC.WaitForPendingFinalizers();

垃圾收集器似乎在本地方法范围内保留了一份分配的副本,因此通过创建一个新的方法范围并退出,GC 通常会释放资源。到目前为止,这很适合我的调试目的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 1970-01-01
    相关资源
    最近更新 更多