gpt4 book ai didi

c# - .NET GC 删除正在使用的对象

转载 作者:太空宇宙 更新时间:2023-11-03 18:27:46 36 4
gpt4 key购买 nike

我遇到了一个问题,GC 线程似乎正在唤醒并删除正在使用的对象。

当 processfoo 正在运行时,在它返回之前,似乎 fooCopy 析构函数在一个单独的线程中触发。有没有人见过这样的问题,如果有,你是如何解决的?当然,这不可能真的发生,我一定是做错了什么。谁能给我一些调试垃圾收集的技巧/策略?

try
{
CFoo fooCopy = new CFoo(someFoo);
someBar.ProcessFoo(fooCopy);
}

CFoo 有一个 IntPtr 成员变量。ProcessFoo 将该成员变量传递给从 C++ DLL 导入的函数,该函数可能需要几秒钟才能运行。

在我的 C++ DLL 中,我记录 IntPtr 的创建时间和删除时间,我可以看到一个单独的线程在 ProcessFoo 运行时删除 IntPtr。

最佳答案

Surely, this can't be really happening and I must be doing something wrong.

不,它可以绝对发生(这就是为什么编写终结器很难,您应该尽可能避免使用它们,并且在被迫编写它们时要非常小心)。只要运行时可以证明没有代码会再次尝试访问对象,就可以对对象进行 GC 处理。如果您调用实例方法(并且在该调用之后的任何时候都从不访问对象实例),则该对象在该实例方法最后一次使用 this 之后立即符合收集条件。

范围内的对象(例如,方法的 this 变量)但在该范围内不再使用的对象不被 GC 视为根对象.

至于如何解决这个问题,如果您有一个您希望被视为“有效”的变量,即使它再也不会在托管代码中被访问,请使用 GC.KeepAlive。在这种情况下,将 GC.KeepAlive(this) 添加到 ProcessFoo 的末尾将确保有问题的对象保持事件状态直到方法结束(或者如果它不是该方法的责任,让调用者在 ProcessFoo 之后立即调用 GC.KeepAlive(someBar)

参见 this blog post有关此主题的更多信息,以及终结器的一些相关甚至更不寻常的属性。

关于c# - .NET GC 删除正在使用的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30036487/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com