w3wp.exe垃圾堆充满了免费对象空间并且不断增长

时间:2015-05-14 09:26:15

标签: memory-leaks garbage-collection heap w3wp.exe

我的IIS应用程序(.NET 4.0,IIS7)在内存中不断增长,并最终坍塌,就好像我有内存泄漏一样。

所以当它上升到大约1.7GB时,我拿了一个DMP并在WinDbg中打开它。

dumpheap -stat命令显示,虽然我在堆中有相当数量的对象,但大多数(以及在查看顺序DMP时增长的位)被标记为" Free" (大于800MB):

  

000007feef55b768 46091 2212368 System.Data.DataRowView
  000007fe9739dda8 10355 2236680 Newtonsoft.Json.Serialization.JsonProperty
  000007fef4260610 33062 2644960 System.Signature
  000007fef4242250 41809 4682608 System.Reflection.RuntimeMethodInfo
  000007fef424f058 69232 8847997 System.Byte []
  000007fef4241b28 11 9437680 System.Double []
  000007fef4237ca0 15 9505176 System.DateTime []
  000007fef424c168 32559 11009308 System.Char []
  000007fef424dc30 17271 11795376 System.Int32 []
  000007feef555c48 908 17936672 System.Data.RBTree`1 + Node [[System.Int32,mscorlib]] []
  000007feef554f58 853 22056952 System.Data.RBTree`1 + Node [[System.Data.DataRow,System.Data]] []
  000007feef5514b0 541444 51978624 System.Data.DataRow
  000007fef424aee0 1550958 132599872 System.String
  000007fef422f1b8 183607 178409288 System.Object []
  0000000000d8b2d0 234017 844500226免费

然后我跑了#34;!dumpheap -type Free"它给了我一个很多的微小的Free对象(确切地说是每个94字节!),最后是几个更大的" Free"对象:

  

00000003098a59b0 0000000000d8b2d0 134免费
  00000003098c19d0 0000000000d8b2d0 102免费
  00000003098ffa00 0000000000d8b2d0 54免费
  0000000309a41d98 0000000000d8b2d0 5961750免费
  000000041f8a1000 0000000000d8b2d0 24免费
  000000042001b4d0 0000000000d8b2d0 16933078免费
  00000004211bf7c8 0000000000d8b2d0 7702免费
  00000004212c1600 0000000000d8b2d0 35173374免费
  00000004236b3be0 0000000000d8b2d0 66886免费
  0000000423cc41e8 0000000000d8b2d0 10778318免费
  0000000424768928 0000000000d8b2d0 2254734免费
  00000004249ec128 0000000000d8b2d0 21166350免费
  000000042600f1e0 0000000000d8b2d0 51366免费
  000000042621bac8 0000000000d8b2d0 114007238免费

Statistics:
              MT    Count    TotalSize Class Name
000007fef31e7460        1           32 System.Net.SafeLocalFree
0000000000d8b2d0   234017    844500226      Free
Total 234018 objects

注意" d8b2d0"的重复地址我跑了一个"!gcroot d8b2d0"  我得到了以下结果:

  

0:000> !gcroot d8b2d0
  找到0个独特的根(运行'!GCRoot -all'查看所有根)。

所以......毕竟......我的大量Free对象卡在我的堆上,GC没有释放。这大约需要2-3个小时。实际键入的对象没有任何其他内存泄漏的迹象。它几乎发生在我们生产的所有虚拟机上。

有没有人知道如何处理GC在堆上留下如此多的Free对象空间?

让我在圈子里跑了好几天。因此,天才可以帮助我解决这个问题!

2 个答案:

答案 0 :(得分:2)

感谢有关使用magicandre1981的PerfView的建议,并且经过相当多的非常大的内存转储之后,我将这个问题归结为在Linq表达式中使用DataRow.DefaultIfEmpty()。它是在两个DataTable之间执行LeftJoin的支持函数的一部分。

使用DataRow枚举中的DefaultIfEmpty()作为Linq表达式的一部分,我可以在几分钟内重新创建内存天空以达到4GB +。通过创建大量的ItemArrayObjects(小型和大型对象堆),大部分都可以通过Gen2 GC集合继续存在。这反过来又导致了不断攀升的记忆价值。 GC2集合无法跟上小堆,并且大堆的重用性很差(如果有的话)。

我们已经接受了这个呼叫,同样的娱乐活动在承诺的内存中永远不会超过50MB。我们现在需要看看这对我们的DataTable连接有何影响,但内存堆之谜已经解决了!

感谢帮助人员。

答案 1 :(得分:0)

如果您确定您的应用程序存在内存泄漏,我建议您使用内存分析器开始本地分析。这可能比分析生产中的内存转储更快地揭示问题的根源。