这是一个未供不应求的项目问题还是大对象堆问题



我正在尝试弄清为什么我们的网站之一使用2.3GB内存。从windbg,当我运行!dumpheap -stat时,我得到了:

000007fe992ae8d8    39413     11489246 System.Byte[]
000007fe992abf40     8567     14995548 System.Char[]
000007fe994500b0    31763     31617136 System.Int32[]
000007fe9c7b4cf8  1221470     48858800 XXXXXXX.SearchService+SectorItem
000007fe9925ba30   219828     49646032 System.Object[]
000007fe992a46f0  4273039    264621916 System.String
0000000002a35c10     2214    923713198      Free
Total 6994094 objects
Fragmented blocks larger than 0.5 MB:
            Addr     Size      Followed by
000000010625ef50    1.2MB 00000001063982e0 System.Collections.Hashtable
00000001064c9ed0    4.4MB 0000000106932128 System.Object[]
0000000206a4ee48    0.6MB 0000000206ae0a10 System.String
0000000206d270a0    3.9MB 0000000207106058 Free
0000000305282098    0.8MB 000000030534d248 System.Xml.XmlElementListListener
00000003053c5ad0    0.9MB 00000003054a87c0 System.String
0000000406a8b0f0    1.9MB 0000000406c73f10 System.WeakReference
0000000406c7aac8    2.2MB 0000000406ea43a8 System.Byte[]
0000000406ef89a8    1.5MB 00000004070721d8 System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.String, mscorlib],[System.DateTime, mscorlib]]
0000000407072208    1.2MB 00000004071a77c0 System.Threading.ThreadPoolWorkQueueThreadLocals
00000004073d1110   11.3MB 0000000407f1a7f8 Free

我们可以看到,有超过900MB的"免费"对象,并且从未从IIS内存中释放(因为我看了几天的图表(。如果我这样做,则有2200个免费对象:

!dumpheap -mt 0000000002a35c10

有很多免费对象:

00000005310b8008 0000000002a35c10       30 Free
00000005310dce28 0000000002a35c10       30 Free
0000000531101a50 0000000002a35c10       30 Free
0000000531126870 0000000002a35c10       30 Free
000000053114c680 0000000002a35c10       30 Free
0000000531187ee8 0000000002a35c10       30 Free
00000005311c3538 0000000002a35c10       30 Free
00000005311fefe0 0000000002a35c10 18583286 Free
0000000532a5e3a0 0000000002a35c10  9499822 Free
0000000533383848 0000000002a35c10  9830638 Free
0000000533d98db8 0000000002a35c10 46462326 Free
0000000536a40d70 0000000002a35c10       30 Free
0000000536a6f300 0000000002a35c10 10549646 Free
00000005374cf138 0000000002a35c10 10246582 Free
0000000537ee4f98 0000000002a35c10 80664406 Free
000000053cccb570 0000000002a35c10 22118654 Free

根据本文:https://www.simple-talk.com/dotnet/.net-framework/the-dangers-of-the-large-object-heap/任何大于85000 by的东西都不会自动回忆。因此,我能得出结论,我们的内存中有一些非常大的对象(例如,大型词典(,并且从未被GC删除吗?因此,这是一个LOH问题,而不是记忆泄漏问题?

如果是LOH问题,如果大型对象在缓存中(重复使用(或一次用于内存中,是否有任何区别?GC会收集其中的任何一个吗?

不会自动回忆大于85000 byt。

它将被收集,但不会包含在GC堆的压实中。

所以我可以得出结论,内存中有一些非常大的对象[...]

不是来自给定数据的。如果两个Free区域互相跟随,则将组合成更大的区域。因此,一个9 MB Free区域可能是1000个"小"对象的9000字节,每个对象随后在存储器中对齐。

[...],永远不会被GC删除?

它们已经被GC删除,因为它是Free。这些不是Free类型的对象。它确实是从.NET的角度免费的,当您创建新对象时,.NET框架将重复使用。

但是,该内存尚未使用VirtualFree()调用从.NET返回到OS。因此,从OS的角度来看,内存仍在使用中。

所以这是一个loh问题[...]

不可能在不知道GC堆的边界的情况下说出。尝试!eeheap以查看几代开始或使用sosex'!dumpgen倾倒特定的GC堆,仅查看它是否包含Free对象。

[...]除了记忆泄漏问题?

这不是内存泄漏,因为垃圾收集器已释放了内存。您的开发人员不能做太多使.NET将记忆返回到操作系统的情况。由于某种原因,.NET认为它应该保留记忆以供以后使用。

如果大型对象在缓存中(重复使用(或一次用于内存中,是否有任何区别?

如果缓存引用该对象,则不会收集该对象(如果不是弱参考(。然后,您将不再看到Free对象,而是真实的对象。

GC会收集其中的任何一个吗?

GC将收集未参考的对象,并可能收集弱参考引用的对象(缓存可能使用(。

最新更新