.net内存未被回收

时间:2015-08-10 12:44:03

标签: .net garbage-collection

我有一个'服务'(owin / webapi + odp.net managed),它在x64机器上运行'server gc mode'。执行测试套件后,内存使用量约为2Gb。我'在那台机器上产生了'内存压力'(另一个消耗了所有可用内存的程序)。我原以为Windows会强制.net释放一些内存。但事实并非如此。这是windbg的输出:

0:018> !dumpheap -stat
Statistics:
              MT    Count    TotalSize Class Name
00007ffd10445b90        1           24 System.Collections.Generic.GenericEqualityComparer`1[[System.UInt64, mscorlib]]
...
00007ffd0f904918   100864     11616976 System.Object[]
0000005b19face20       84   1810674044      Free
Total 720544 objects
Fragmented blocks larger than 0.5 MB:
            Addr     Size      Followed by
0000005b1c3c8800  425.6MB 0000005b36d56c50 System.Func`2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]]
0000005c1c3fcf00   28.2MB 0000005c1e02be58 System.Reflection.Emit.MethodBuilder
0000005c1e02e5b0  268.0MB 0000005c2ec313d8 System.Threading.OverlappedData
0000005c2ec31678  142.3MB 0000005c37a830a0 System.Func`2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]]
0000005d1c541aa0  404.8MB 0000005d35a1a958 System.Func`2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]]
0000005d35a1e5a8    3.8MB 0000005d35df0c40 System.Func`2[[System.IAsyncResult, mscorlib],[System.Net.HttpListenerContext, System]]
0000005e1cfe7128  444.1MB 0000005e38c0c3f0 System.Byte[]
0000005e38c8cfb8    4.5MB 0000005e39110988 System.Byte[]
0000005e39111bf8    1.2MB 0000005e3923a570 System.Byte[]
0000005e3923b7e0    0.7MB 0000005e392ed7d0 System.Byte[]
0000005e392eea40    1.1MB 0000005e39401910 System.Byte[]

0:018> !heapstat
Heap             Gen0         Gen1         Gen2          LOH
Heap0       455256040           24           24      3713672
Heap1       464550872           24      4327776       727456
Heap2       428541352     10344768        12616           24
Heap3       474250128           24     21350456           24
Total      1822598392     10344840     25690872      4441176

Free space:                                                 Percentage
Heap0       446429064            0            0      1819552SOH: 98% LOH: 48%
Heap1       459823968            0          144          152SOH: 98% LOH:  0%
Heap2       428520936        34904           24           24SOH: 97% LOH:100%
Heap3       474044952            0          336           24SOH: 95% LOH:100%
Total      1808818920        34904          504      1819752

因此,实际上只有大约48Mb和1.8Gb可用,大部分内存不在LOH中但在Gen 0堆中,但.net不会给回内存。同时系统正在挨饿。例如,IIS无法启动,因为内存不足。

为什么Windows没有回收内存?

2 个答案:

答案 0 :(得分:2)

好的窗户不能“强制”.Net来释放内存。虽然我不是.Net运行时的专家,但我的经验是,一旦你的应用程序开始消耗很多内容,.net框架就会保留在内存中。它会慢慢回复,因为它看起来很合适。从Windows的角度来看,它并不真正知道.Net会用它做什么,但它.Net已声称来自操作系统的内存,直到它(.net)将窗口返回窗口,无法将内存提供给另一个应用程序。 System.Byte []有几个400 + mb的块被保留,这可能表示存在内存泄漏。从操作系统的角度来看,框架已经请求了内存甚至使用了那个内存,所以直到它明确地(从框架而不是你)给出后面的窗口无法做任何事情。我会非常仔细地描述您的应用程序,因为.Net通常不释放内存的原因是因为您有内存泄漏。使用Visual Studio中的内存分析工具应该向您显示您是将内存“固定”还是只是保留它。真正坏的罪魁祸首通常是静态类变量/事件。

SO link:.NET Free memory usage (how to prevent overallocation / release memory to the OS)

答案 1 :(得分:0)

因为,Windows无法压缩应用程序以释放对象。您需要找到一种方法来定义应用程序的最大内存使用量。达到最大限制时,通过GC.Collect()手动调用垃圾收集器。

当应用程序运行时,尝试获取Process&设置maxLimit,类似于this