【发布时间】:2018-11-17 10:22:50
【问题描述】:
我无法解释 C# 进程使用的大部分内存。总内存为 10 GB,但可达和不可达对象的总和为 2.5 GB。我想知道这 7.5 GB 可能是什么?
我正在寻找最可能的解释或方法来找出这段记忆可能是什么。
这是确切的情况。该过程是.NET 4.5.1。它从互联网下载页面并使用机器学习对其进行处理。如 VMMap 所示,内存几乎完全位于托管堆中。这似乎排除了非托管内存泄漏。
进程已经运行了好几天,内存慢慢增长。在某些时候,内存为 11 GB。我停止了该过程中运行的一切。我多次运行垃圾收集,包括large object heap compaction(间隔一分钟):
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
内存降至 10 GB。然后我创建转储:
procdump -ma psid
转储为 10 GB,符合预期。
我使用.NET memory profiler(5.6 版)打开转储。转储显示总共 2.2 GB 可达对象和 0.3 GB 不可达对象。 什么可以解释剩余的 7.5 GB?
我一直在想的可能解释:
- LOH 并未真正完全压缩
- 在分析器显示的对象之外使用了一些内存
【问题讨论】:
-
这相当于“发生内存泄漏,请修复。”。你的服务是做什么的?它会调用任何不受管理的东西吗?它使用 COM 吗?
-
GC 后不应该有那么多无法访问的对象。死锁的终结器线程导致内存爆炸,使用 WinDbg 看看它在做什么。
-
谢谢汉斯。这段遥不可及的记忆对我来说确实很可疑。我去看看。
-
听起来像是非托管内存使用。 JetBrains 分析器可以证明这一点。您也可以使用免费的 VMMap.exe 来测试该理论。
-
谢谢你。我检查了VMMap。我的 10 GB 中有 95% 位于托管堆中。这似乎排除了非托管内存的使用。
标签: c# memory-profiling large-object-heap