Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.NET进程内存使用率=5x CLR堆内存?_.net_Memory_Process_Clr_Heap - Fatal编程技术网

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

.NET进程内存使用率=5x CLR堆内存?,.net,memory,process,clr,heap,.net,Memory,Process,Clr,Heap,我正在努力解决一些内存使用问题。总的来说,我的应用程序收集了一些数据值,并使用c1wpf图表和数据网格将它们可视化,最后将所有内容放入PDF报告中 使用YourKit评测我的进程我面临的情况是,CLR堆大小约为120MB(这很好),而进程内存大小约为580MB。这几乎是我实际CLR堆大小内存消耗的5倍。我的CLR峰值大小为220MB,而进程内存分配为710MB 我很清楚,我的对象堆、堆栈等都需要一些开销。在Java JVM中,我习惯的典型因素大约是1.5倍 如何解释这种过度的内存开销?进程只是分

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

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

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


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

如果托管堆的总大小明显小于应用程序使用的专用字节,则可能是您正在分配非托管内存,并且(可能)没有正确处理它。实现IDisposable的图形对象、流和其他对象需要在超出作用域之前调用其
Dispose()
方法,或者将其放入
using(){}
语句中,以便清理所有非托管资源。使用像ANTS Memory Profiler这样的工具可以向您展示内存是如何分配的,以及哪些对象实现了IDisposable。

这里有一些附加说明。虽然我不太清楚“CLR堆大小”是什么意思。 CLR使用大约8个不同的堆—因此,堆大小与VM大小之间的内存差异可以解释其中的一些差异:

  • 加载程序堆:包含CLR结构和类型系统
  • 高频堆:statics、MethodTables、fielddesc、接口映射
  • 低频堆:EEClass、ClassLoader和查找表
  • 存根堆:CAS存根、COM包装器、P/Invoke
  • 大型对象堆:需要超过85k字节的内存分配
  • GC堆:用户分配给应用程序的专用堆内存
  • JIT代码堆:由mscoreee(执行引擎)和JIT编译器为托管代码分配的内存
  • 进程/基本堆:互操作/非托管分配、本机内存等
  • 另外两个可能导致内存过度使用的项目是内存碎片(主要发生在LOH或大型对象堆上)或大量线程

    内存碎片的原因有很多,最好的解决方法是使用WinDbg分析GC堆上每个段的段大小

    对于大量线程,应用程序使用的每个线程都有1MB的堆栈空间。此内存放在进程/基本堆中。因此,如果您有100个线程,您将有额外的100MB内存使用


    谢谢你,丹!这正是我丢失的指针。在这里,ANTS可能也帮不上忙(我已经在使用YourKit),因为它无法跟踪非托管内存泄漏。目前,我正在尝试使用DebugDiag 1.2解决我的问题。我不熟悉DebugDiag,但Smartbear的AQTime允许您分析托管和非托管代码。它不像蚂蚁那么容易使用,但是有更多的信息可用。非常感谢您的宝贵和广泛的注释,特别是有关.NET内存分配的剖析和潜在问题的注释。在我的例子中,最终证明是C1图形组件,它通过GDI+使用了大块内存。作为一名Java专家,我完全困惑于无法通过.NET内存分析器工具看到这一点。最后,我们必须通过限制C1图形组件的使用来解决这个问题。很高兴能提供帮助。我不得不用WinDbg调试许多内存转储,这教会了我很多。在使用第三方组件时,我会关注两件事:首先,确保它们已被处理,其次,关注应用程序正在使用的句柄数量。这可以通过使用TaskManager(确保句柄列可见)或SysInternals ProcessExplorer轻松完成。通常,您会使用“using()”语句来确保及时处理组件。但是我不熟悉WPF,所以这个框架可能已经处理好了。Ben,你怎么知道GDI+在消耗内存?