【发布时间】:2023-03-06 10:36:01
【问题描述】:
我正在调查 PerfMon 和 WinDbg 的内存泄漏问题。我注意到“大内存堆”计数器从 10MB 增加到 37MB。强制 GC 后,它只能减少到 28MB。
(无论我重复多少次操作(create/destroy),GC后大对象堆稳定在28MB)。
我想知道哪些对象会导致泄漏问题,因此我使用 '!Dumpheap -min 85000' 命令运行 WinDbg。捕获了两张快照,第一张是在内存泄漏之前完成的;第二个是内存泄漏后:
之前:
MT Count TotalSize Class Name
6f39fb08 1 89024 System.String
6f3a4aa0 1 107336 System.Byte[]
6f356d84 2 262176 System.Object[]
00360e4c 1 350392 System.Collections.Generic.Dictionary`2+Entry[Int64,Int32][]
6f3a2a94 3 592584 System.Int32[]
00360c24 1 727072 System.Collections.Generic.Dictionary`2+Entry[String,Int64][]
0bc78b34 4 2754488 System.Collections.Generic.Dictionary`2+Entry[Int64, AccountNode][]
00730260 10 5375572 Free
之后:
MT Count TotalSize Class Name
6f39fb08 1 89024 System.String
6f3a4aa0 1 107336 System.Byte[]
6f3a55d8 2 202080 System.Collections.Hashtable+bucket[]
6f356d84 2 262176 System.Object[]
00360e4c 1 350392 System.Collections.Generic.Dictionary`2+Entry[Int64,Int32][]
00360c24 1 727072 System.Collections.Generic.Dictionary`2+Entry[String,Int64][]
6f3a2a94 4 738008 System.Int32[]
6cf02838 1 872488 System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.ComponentModel.PropertyKey, WindowsBase],[MS.Internal.ComponentModel.DependencyPropertyKind, WindowsBase]][]
0bc78b34 4 2754488 System.Collections.Generic.Dictionary`2+Entry[Int64, AccountNode][]
00730260 14 21881328 Free
Total 31 objects
对比这两个快照,最大的区别是'Free'的大小。它的大小增加了近 16MB。 谁能告诉我“免费”是什么意思,是免费空间吗?增加是由碎片引起的吗?
根据this article,“大对象堆大小”性能计数器似乎包括可用空间。 所以在我的情况下,大对象堆上没有太多的内存泄漏,只有 2MB (= 28 - 10 -16),对吧?
【问题讨论】:
-
这不是泄漏。这个是正常的。不要不要调用GC.Collect(),这是非常有害的。在您的程序开始使用过多的内存或内存或因 OOM 崩溃之前,不要追逐“泄漏”。 37MB 是花生。通过 CLR 阅读 Richter 的 C# 之类的好书自学。
-
感谢您的回复。我同意你的观点,我们不应该在产品代码中调用 GC.Collect()。我不明白为什么不追查“泄漏”问题?据我所知,尽可能多的“垃圾”留在堆中,发生了尽可能多的 GC。在我看来,我们应该追逐它并减少不必要的refrenent(即unregist event),这可能会导致内存泄漏问题。
标签: c# memory-leaks windbg