我正在运行一个为 HTTP 请求提供服务的 C# 应用程序。我最近注意到它占用的内存比我预期的要多。我抓了一些转储,在 Windbg 中弹出,发现大部分内存都标记为 Free:
!dumpheap -stat
...
00007ffde4783630 681599 65433504 System.Threading.Tasks.TaskFactory+CompleteOnInvokePromise
00007ffde47cc988 167885 76872908 System.Byte[]
00007ffde47c6948 521353 80352802 System.String
0000007e3a16c2d0 1870425 1415374334 Free
因此转储约为 3GB,因此其中大约一半是可用内存。看着堆,我看到了这个:
!heapstat
Heap Gen0 Gen1 Gen2 LOH
Heap0 82248472 7354560 987275056 178834656
Heap1 93146552 6382864 857470096 129435960
Total 175395024 13737424 1844745152 308270616
Free space: Percentage
Heap0 40969256 146456 640426720 54829792 SOH: 63% LOH: 30%
Heap1 75943736 94448 550812312 54825216 SOH: 65% LOH: 42%
Total 116912992 240904 1191239032 109655008
所以我的小对象堆非常分散,特别是 Gen2。在服务器上,我可以看到正在发生 gen2 集合(使用性能计数器),但即使它们是,看起来 gen2 堆也没有被压缩。即使服务器上只有 1-2% 的 RAM 可用,gen2 堆也不会被压缩。
对我来说,看起来我正在承受这种内存压力,因为堆是碎片化的。但是我无法弄清楚为什么会发生碎片或为什么 gen2 无法被压缩。一些可用空间的大小为 6MB,所以我认为它肯定会压缩这些空间。
谁能给我一些关于如何弄清楚为什么我的堆如此分散的想法?我什至在这里吠叫正确的树吗?
任何帮助将不胜感激,谢谢!
编辑1:
细分!gchandles
为:
Handles:
Strong Handles: 4507
Pinned Handles: 58
Async Pinned Handles: 977
Ref Count Handles: 1
Weak Long Handles: 6087
Weak Short Handles: 724