.NET垃圾收集.内存泄漏.进程使用GB的专用字节,但是GC.NET内存计数器只显示几个MB



我最初不信任从perfmon集合返回的结果,因为进程似乎存在内存泄漏。

进程的Private Bytes值超过一个gig。

所以我怀疑垃圾回收无法清除内存,因为有东西像回收等一样打开了引用。

但是,.NET内存计数器显示Gen 0,1,2堆大小的意外值。

例如,perfmon在所有堆中为#Bytes返回的值只有几百万字节(即几个MB)。大型对象大小也很小。

我承认我有点困惑。我认为这意味着内存分配在托管内存之外,或者这是一个错误?

#

编辑

  1. 我遗漏的一个重要点是GC有好几个星期没有被调用

  2. 我有一个大约一周前捕获的VMMap输出,我担心再次在prod中运行VMMap,所以我不能再次捕获(除非有人知道VMMap有多安全?)

我的VMMap显示托管堆的大小接近900000 KB,私有字节数超过500000 KB,当我看到perfmon值时,我觉得很奇怪。

托管堆将始终是私有字节的子集。专用字节是进程要求的内存量。这包括由运行时本身或进程加载的任何其他模块完成的本机分配。

此外,CLR将托管堆的存储分配为称为段的块。托管堆基本上是段的集合。CLR根据需要分配和释放这些段。在任何给定的时间点,托管堆上通常都会有"可用"空间。即,段贡献了私有字节数,但CLR认为内存是空闲的。

你的第一个行动应该是弄清楚什么样的记忆占据了这个空间。如果是托管内存,则可以使用内存探查器或调试器(如WinDbg/SOS)检查托管堆。

最新更新