我正在努力解决一些内存使用问题。总体而言,我的应用程序收集了一些数据值,并使用C1 WPF图表和数据网格将其可视化,最终将所有内容都放入PDF报告中。
使用YourKit分析我的进程我面临的情况是,CLR堆大小约为120MB(这很好),而进程内存大小约为580MB。这几乎是我实际CLR堆大小的内存消耗的5倍。我的CLR峰值大小为220MB,而710MB进程内存分配。
我很清楚我的对象堆,堆栈等需要一些开销。在Java JVM中,我习惯的典型因素是大约1.5倍。
如何解释这种过多的内存开销?进程只是分配空闲的备用堆空间吗?如果是,这是否解释了710MB与220MB?
答案 0 :(得分:11)
这里还有一些补充说明。虽然我不太明白你的意思是“CLR堆大小”。 CLR使用了大约8种不同的堆 - 因此您在堆大小与VM大小中看到的内存占某些的差异:
可能导致内存使用过多的另外两个项是内存碎片(主要发生在LOH或大对象堆上)或大量线程。
内存碎片有很多原因,排除这种情况的最佳方法是使用WinDbg分析GC堆上每个段的段大小。
对于大量线程,您为应用程序使用的每个线程分配了1MB的堆栈空间。此内存放在Process / Base堆中。因此,如果你有100个线程,你将有额外100MB的内存使用。
HTH
答案 1 :(得分:2)
如果托管堆的总大小明显小于应用程序使用的专用字节,则可能是您正在分配非托管内存并且(可能)未正确处理它。实现IDisposable的图形对象,流和其他对象需要在它们超出范围之前调用它们的Dispose()
方法,或者放在using(){}
语句中,以便清除任何非托管资源。使用像ANTS Memory Profiler这样的工具可以向您展示如何分配内存以及哪些对象实现IDisposable。