对象不是垃圾收集,但不包含gcroots

Lac*_*nia 13 asp.net debugging windbg

在这里遇到我们的网络应用程序的棘手问题.(Asp.net 2.0 Win server 2008)

我们对网站的内存使用量增长和增长,即使我希望它保持在相当静态的水平.(我们有少量数据存储在状态中).

想要找出问题所在,我运行了一个System.GC.Collect(); 几次,采取内存转储,然后将此内存转储加载到WinDbg.

当我执行DumpHeap -Stat时,我会在内存中挂起特定类型的非常大的数字.

0000064280580b40 713471 79908752 PaymentOption

所以,为这种类型做一个DumpHeap -MT,我得到一堆对象引用.挑选一些随机数,我做了一个!gcroot,命令回来报告没有引用它.

对我而言,这正是GC应该收集这些项目的时候,但由于某种原因,它们一直处于劣势.

任何人都可以解释可能发生的事情吗?

小智 5

您可以尝试在 Windbg 中使用sosex.dll,这是一个用于帮助 .NET 调试的扩展。有一个名为 !refs 的命令,它类似于 !gcroot,它会显示所有引用一个对象的对象,另外还会显示它也引用的所有对象。

在作者网站上的示例中,!refs 用于对象,输出如下所示:

0:000> !refs 0000000080000db8
Objects referenced by 0000000080000db8 (System.Threading.Mutex):
0000000080000ef0         32    Microsoft.Win32.SafeHandles.SafeWaitHandle 

Objects referencing 0000000080000db8 (System.Threading.Mutex):
0000000080000e08         72    System.Threading.Mutex+<>c__DisplayClass3
0000000080000e50         64    System.Runtime.CompilerServices.RuntimeHelpers+CleanupCode
Run Code Online (Sandbox Code Playgroud)


n8w*_*wrl 1

并非没有有关您的应用程序的更多信息。但我们很久以前就遇到了一些令人讨厌的记忆问题。您使用 ASP.NET 缓存吗?正如 Raymond Chen 喜欢说的那样,“糟糕的缓存策略与内存泄漏没有区别。”

查看另一个工具 - CLRProfiler.exe - 它将帮助您遍历对象引用树以查看对象的根位置。这也很好:链接文本

您以前听说过这一点 - 如果您必须进行 GC.Collect,则说明有问题。