调试期间是否运行垃圾收集?
我有一个程序可以打开 Excel COM 对象,执行一些操作,然后关闭它。然后我想在关闭后移动该文件。如果我在没有断点的情况下运行程序,则效果很好。但是,如果我在尝试移动文件之前进入调试模式,则会收到 IOException:“该进程无法访问该文件,因为该文件正在被另一个进程使用。”
那么到底是怎么回事呢?当程序被允许全速运行时,垃圾收集的性能是否比我单步执行时更好?单步执行我的代码不仅仅是非常缓慢地运行它吗?调试模式还有其他后果吗?仅仅因为我处于调试状态并且没有运行 exe 而遇到其他错误?
I have a program that opens an Excel COM object, does some stuff, and closes it. Then I want to move that file after it's closed. This works fine if I run the program without break points. But, if I step into something in debug mode before I attempt to move the file I get an IOException: "The process cannot access the file because it is being used by another process."
So what's the deal? Is garbage collection performing better while a program is allowed to run at full speed as opposed to while I am stepping through it? Is stepping through my code doing more than just very slowly running it? Are there other consequences to the debug mode? Other errors that are encountered simply because I am in debug and not running an exe?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,当不在调试器中运行时,垃圾收集的优化方式有所不同。特别是,CLR 可以检测到变量不会用于方法的其余部分,并不再将其视为 GC 根。在调试器中,作用域中的变量在整个方法中充当 GC 根,以便您仍然可以使用调试器检查这些值。
但是,这应该很少成为问题 - 如果终结器实际上执行了一些清理,并且如果您显式及时清理事情(例如使用
using
语句)您通常不会注意到其中的差异。Garbage collection is optimized differently when running not in the debugger, yes. In particular, the CLR can detect that a variable won't be used for the rest of a method, and treat it as not a GC root any more. In the debugger, variables in scope act as GC roots throughout the method so that you can still examine the values with the debugger.
However, that should rarely be a problem - it should only affect things if a finalizer actually performs some clean-up, and if you're explicitly tidying things up in a timely way (e.g. with
using
statements) you usually wouldn't notice the difference.根据记录,我也遇到过几次这种情况。我发现这在调试模式下测试调用本机端代码的终结器时有效:
垃圾收集器似乎保留了本地方法范围内的分配副本,因此通过创建新的方法范围并退出,GC 通常会释放资源。到目前为止,这对于我的调试目的来说效果很好。
For the record, I ran into this as well a few times. I found that this works when testing finalizers calling native side code in debug mode:
The garbage collector seems to keep a copy of allocations rooted within the local method scope, so by creating a new method scope and exiting, the GC usually releases the resource. So far this works well for my debugging purposes.