.NET进程内存使用量= 5x CLR堆内存?

ben*_*lor 4 .net memory heap clr process

我正在尝试解决一些内存使用问题.总的来说,我的应用程序收集了一些数据值,并使用C1 WPF图表和数据网格将它们可视化,最终将所有内容都放入PDF报告中.

使用YourKit分析我的进程我面临的情况是,CLR堆大小约为120MB(这很好),而进程内存大小约为580MB.这几乎是我实际CLR堆大小的内存消耗的5倍.我的CLR峰值大小为220MB,而710MB进程内存分配.

我很清楚我的对象堆,堆栈等需要一些开销.在Java JVM中,我习惯的典型因素是大约1.5倍.

如何解释这种过多的内存开销?进程只是分配空闲的备用堆空间吗?如果是,这是否解释了710MB与220MB?

Dav*_*ack 12

这里还有几个补充说明.虽然我并不确定你的意思是"CLR堆大小".CLR使用了大约8种不同的堆 - 因此您在堆大小与VM大小中看到的内存占了一些差异:

  1. Loader Heap:包含CLR结构和类型系统
  2. 高频堆:静态,MethodTables,FieldDescs,接口映射
  3. 低频堆:EEClass,ClassLoader和查找表
  4. Stub Heap:CAS,COM包装器,P/Invoke的存根
  5. 大对象堆:需要超过85k字节的内存分配
  6. GC堆:用户分配的堆内存专用于应用程序
  7. JIT代码堆:由mscoreee(执行引擎)分配的内存和托管代码的JIT编译器
  8. 进程/基本堆:互操作/非托管分配,本机内存等

可能导致过多内存使用的另外两个项是内存碎片(主要发生在LOH或大对象堆上)或大量线程.

内存碎片有很多原因,排除这种情况的最佳方法是使用WinDbg分析GC堆上每个段的段大小.

对于大量线程,您为应用程序使用的每个线程分配了1MB的堆栈空间.此内存放在Process/Base堆中.因此,如果您有100个线程,则将有额外的100MB内存使用量.

HTH