【问题标题】:.NET Garbage Collection. Memory Leak. Process using GBs of Private Bytes yet GC .NET Memory counters show only a few MBs.NET 垃圾收集。内存泄漏。使用 GB 的私有字节进行处理,但 GC .NET 内存计数器仅显示几 MB
【发布时间】:2015-01-03 10:46:14
【问题描述】:

我最初不相信从 perfmon 集合返回的结果与似乎存在内存泄漏的进程有关。

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

所以我怀疑垃圾收集无法清除内存,因为某些东西正在保持打开的引用,例如收集等。

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

例如,perfmon 为所有堆中的 # 字节带回的值只有几百万字节(即几 MB)。 Large Object Size 也非常小。

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

#

编辑

  1. 我遗漏的重要一点是 GC 已经好几周没有被调用了

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

我的 VMMap 显示托管堆的大小接近 900,000 KB,私有字节超过 500,000 KB,当我看到 perfmon 值时,这让我感到很奇怪。

【问题讨论】:

  • 我将首先使用 VMmap 查看您的程序以了解其内存使用情况。那么请向我们提供有关结果的信息。
  • 我有一个一周前的 VMMap 捕获。我将使用此信息编辑问题
  • 这可能是大内存碎片的迹象。但是你关于 GC 几周没有调用的注释很有趣,你是怎么得到的?创收柜台?然而,这是分析完整内存转储的完美场景。你有吗?
  • 是的,性能计数器。不幸的是,没有,因为它是产品
  • 如果没有转储,将很难理解发生了什么。如果您的应用程序是负载平衡的,请尝试在禁用它后使其上线。制作这种大小的转储将停止应用程序池(根据我的经验)长达 30 秒。另一种方法是在负载测试的帮助下尝试在测试环境中模仿这种行为。

标签: .net memory-management memory-leaks garbage-collection perfmon


【解决方案1】:

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

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

您的第一个动作应该是找出占用空间的内存类型。如果是托管内存,您可以使用内存分析器或调试器(例如 WinDbg/SOS)检查托管堆。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2018-05-10
  • 1970-01-01
  • 1970-01-01
  • 2012-01-03
  • 2012-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多