wordpress虚拟主机如何安装,杭州网站建设 seo,seo公司北京,南昌seo锐创一#xff1a;背景 在洞察 GC 方面#xff0c;我觉得市面上没有任何一款工具可以和 PerfView 相提并论#xff0c;这也是为什么我会在 WinDbg 之外还要学习这么一款工具的原因#xff0c;这篇我们先简单聊聊 PerfView 到底能洞察 GC 什么东西#xff1f;二#xff1a;洞察…一背景 在洞察 GC 方面我觉得市面上没有任何一款工具可以和 PerfView 相提并论这也是为什么我会在 WinDbg 之外还要学习这么一款工具的原因这篇我们先简单聊聊 PerfView 到底能洞察 GC 什么东西二洞察 GC 1. 到底都能看到 GC 什么能获取到的 GC 信息非常多比如程序运行期间 GC 触发了多少次GC 最大一次暂停耗费了多久每一次 GC 触发的原因是什么GC 暂停 200ms 的都有哪些GC 触发 3 阶段中各个函数的耗时是怎样的等等。。。可获取的信息非常多后面的文章会逐一聊。2. 获取 GC 的一般性信息为了方面讲述先上一段故意无限次拼接 string 的代码让 GC 高频触发。internal class Program{static void Main(string[] args){Task.Run(Alloc1);Console.ReadLine();}static void Alloc1(){var s string.Empty;for (int i 0; i 100000; i){s s i.ToString();}}}接下来我们用 Collect - Run 对程序采样 20s观察这 20s 中 GC 的触发情况。稍等20s后在打包好的 zip 视图列表中点击 Memory - GCStats。然后点击我们的应用程序就会看到 GC 汇总信息。GC Stats for Process 3848: ConsoleApp10•CommandLine: D:\net6\ConsoleApp1\ConsoleApp10\bin\Debug\net6.0\ConsoleApp10.exe
•Runtime Version: V 6.0.522.21309 (built on 2022/4/14 1:31:32)
•CLR Startup Flags: 8388611
•Total CPU Time: 10,471 msec
•Total GC CPU Time: 1,305 msec
•Total Allocs : 38,099.086 MB
•GC CPU MSec/MB Alloc : 0.034 MSec/MB
•Total GC Pause: 2,710.6 msec
•% Time paused for Garbage Collection: 19.9%
•% CPU Time spent Garbage Collecting: 12.5%
•Max GC Heap Size: 14.285 MB
•Peak Process Working Set: 40.776 MB
•Peak Virtual Memory Usage: 5,003.682 MB
...接下来看下 GC Rollup By Generation 列表如下图所示从图中可得知这 20s 期间的如下信息GC触发了 1w 次平均 500次/s哈GC总的暂停时间是 2.7s占比 13.5% 也就是说20s时间程序其实就跑了 86.5% 的时间有点像 公摊面积 哈 其实这是有问题的。1w 次GC 中最大的单次暂停时发生在 gen0 上耗费了 2.6ms。还有一个比较有用的是 Pause 200 Msec GC Events 列表它记录着那些暂停时间大于 200ms 的单次GC截图如下还好本次实验没有遇到不过可以肯定的是大于 200ms 的程序暂停肯定会导致明显的卡顿所以仔细研读下这些 列信息 非常有用是不是因为 存活对象过多 导致的 mark_phase 和 compact_phase 时间过长还是因为 pinned 或者 碎片化过多导致 plan_phase 时间过长等等具体问题具体分析。接下来就是这 10956 次 GC 的 detail 信息啦可以观察到 GC 的触发原因触发了哪一代 GCSuppendEE 暂停时间GC 暂停时间GC 与上次 GC 之后的一个时间占比 等等各种信息大家可以把鼠标放在标头上都有相应的提示。稍微提醒下就是 Pause Start 是没有解释的其实它是一个毫秒时间戳如果你仔细观察也就是 500次/s 的排序记录。3. 获取 GC 内部函数的 一般性耗时熟悉 GC 的朋友应该知道最简单的非并发工作站模式 GC 是这样的一个触发模式如下代码所示GarbageCollectGeneration(){SuspendEE();garbage_collect();RestartEE();}garbage_collect(){generation_to_condemn();gc1();}gc1(){mark_phase();plan_phase();}plan_phase(){// actual plan phase work to decide to // compact or notif (compact){relocate_phase();compact_phase();}elsemake_free_lists();}那如何用 PerfView 去检测这些函数的耗时呢可以是可以但只是一个大体的模型因为原理是对 CPU 进行采样 再根据权重算出来的所以有一定的参考意义。接下来我们在 Find 输入框中搜索 coreclr!GarbageCollectGeneration 关键词。接下来右键选择 Goto - Goto Item in Callees 选项然后展开可能的耗时如下图所示从输出信息看, GarbageCollectGeneration 大概会耗时 12.2ms 耗时比较长的两块大概是GCScanRoots在标记阶段爬线程栈耗时相对较大耗费了 3.8ms继续往下翻的话会发现都耗费在寻找 GC 安全点上。relocate_phase这个属于 计划阶段 的重定位阶段主要用来修改需要移动对象的新地址所谓 兵马未动粮草先行。关于 GC 的洞察还有更多好玩的东西放在后续文章聊吧