我正在运行 .NET 4.8 x64 (4.8.4300.0),在 ca 之后。14h压力测试GC时间比开始时高很多。使用 PerfView 我可以看到 Gen0 Heap 的大小增长了很多。Gen0 堆大小和 .NET 4.8 是否存在已知问题?
- 总 CPU 时间:136,245 毫秒
- 总 GC CPU 时间:7,171 毫秒
- 总分配数:10,023.772 MB
- GC CPU MSec/MB 分配:0.715 MSec/MB
- GC 暂停总时间:8,361.5 毫秒
- 垃圾收集暂停时间百分比:5.5%
- 垃圾收集所花费的 CPU 时间百分比:5.3%
- 最大 GC 堆大小:460.052 MB
- 峰值进程工作集:1,166.688 MB
- 峰值虚拟内存使用量:7,314.285 MB
- 总 CPU 时间:141,466 毫秒
- 总 GC CPU 时间:14,364 毫秒
- 总分配:10,235.755 MB
- GC CPU MSec/MB 分配:1.403 MSec/MB
- GC 暂停总时间:22,767.4 毫秒
- 垃圾收集暂停时间百分比:13.6%
- 垃圾收集所花费的 CPU 时间百分比:10.2%
- 最大 GC 堆大小:887.517 MB
- 峰值进程工作集:1,916.793 MB
- 峰值虚拟内存使用量:8,047.583 MB
当我从 ETW 绘制各种迭代计数的 GC、后台 GC 和诱导 GC 的 CPU 消耗时,我发现与增加的 GC 成本和迭代计数有明显的相关性。

奇怪的是托管堆并没有真正变得更大。这看起来不像是托管内存泄漏(好吧,它泄漏了一点,但没有那么多),而是一些 GC 问题,还是我以错误的方式查看数据?
更新 1 这是 GC 的调用堆栈,似乎相当昂贵:
Stack Tag, Stack, Weight (in view) (ms)
4, , Background GC, , 245.131400
5, , , [Root], 245.131400
6, , , ntdll.dll!RtlUserThreadStart, 245.131400
7, , , kernel32.dll!BaseThreadInitThunk, 245.131400
8, , , clr.dll!Thread::intermediateThreadProc, 245.131400
9, , , clr.dll!<lambda_29e7ea55b6ca6bda8a02df3a0a3e58b1>::operator(), 245.131400
10, , , clr.dll!WKS::gc_heap::bgc_thread_function, 245.131400
11, , , clr.dll!WKS::gc_heap::gc1, 245.131400
12, , , clr.dll!WKS::gc_heap::background_mark_phase, 245.131400
13, , , |- clr.dll!GCScan::GcScanHandles, 203.131000
14, , , | clr.dll!Ref_TraceNormalRoots, 203.131000
15, , , | clr.dll!HndScanHandlesForGC, 203.131000
16, , , | clr.dll!TableScanHandles, 203.131000
17, , , | clr.dll!BlockScanBlocksWithoutUserData, 203.131000
18, , , | clr.dll!ScanConsecutiveHandlesWithoutUserData, 203.131000
19, , , | |- clr.dll!PromoteRefCounted, 202.131100
20, , , | | |- clr.dll!WKS::gc_heap::background_promote, 196.131800
21, , , | | | clr.dll!WKS::gc_heap::background_mark_simple, 196.131800
22, , , | | | clr.dll!WKS::gc_heap::background_mark_simple1, 196.131800
23, , , | | | |- clr.dll!WKS::gc_heap::background_mark_simple1<itself>, 186.138400
不确定哪些对象可以使成本如此昂贵。但它看起来CPU占主导地位。这是一个 Gen2 GC,它确实需要超过 250 毫秒才能完成






