gpt4 book ai didi

c# - 带有 System.Transactions.SafeIUnknown 的 .NET 垃圾收集器中的内存泄漏

转载 作者:太空宇宙 更新时间:2023-11-03 19:34:53 26 4
gpt4 key购买 nike

我正在尝试使用 ANTS 分析器追踪应用程序中的内存泄漏。我追踪到垃圾收集器,我们有一个对象列表 System.Transactions.SafeIUnknown 永远坐在垃圾收集器中,在终结器队列中但永远不会被释放。

我找不到关于 System.Transactions.SafeIUnknown 的任何文档,也无法确定什么会创建或引用它,这不是我们故意的。

我希望外面的人可能对此有所了解。这是一个 20 字节的小泄漏,但当我们的应用程序连续运行数天时,泄漏就会累积,我们有数百万个等待最终确定的数据,它开始消耗大量内存。

有人知道从这里到哪里去吗?

跟进

我已将其追踪到正在使用的特定库。在我们通过这个特定的库执行任何 SQL 语句后,它似乎被抛在了后面。 statemtements 没有包装在交易中,但它们是通过一个相当复杂的循环执行的,泛型类型和目前看起来像双三重间接寻址的委托(delegate)被传递以进行运动并包装在可以包装在更多闭包中的闭包中。我会继续尝试准确地确定它,我的第一个停靠点是尝试看看我是否可以使用类似的机制重现它。

最佳答案

SafeIUnknown 派生自 SafeHandle。这是实现终结器的类。它很特别,它的终结代码在关键执行区 (CER) 中运行。这种代码提供执行保证,异常被抑制。终结器运行 SafeIUnknown.ReleaseHandle(),它调用 Marshal.Release() 以释放由 SafeIUnknown 包装的 COM 接口(interface)指针。

在终结队列中看到大量此类包装器表明 Marshal.Release() 调用正在抛出异常。防止包装器最终确定。找出它抛出异常的确切原因将很棘手。这是非托管代码轰炸,您几乎没有可用的提示来找出原因。 95% 的情况是堆损坏,这是一个很难解决的问题。最重要的是因为这可能不是您的代码并且您没有任何来源。

您应该能够在良好的非托管代码调试器(如 WinDbug)中在第一次出现异常时获得断点。获取调试符号对于理解堆栈跟踪至关重要。然而,距离那里可能还有很长的路要走。考虑从 Microsoft 支持部门获得帮助。或者像重建机器这样激烈的事情。祝你好运!

关于c# - 带有 System.Transactions.SafeIUnknown 的 .NET 垃圾收集器中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2378983/

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