我有一个相当复杂的 F# 应用程序,我使用 F# 脚本使用#time
指令检查其性能。这个想法是我在更改代码后运行脚本以跟踪性能并避免引入速度或内存问题。
我得到的报告是这样的:
Real: 00:00:02.908, CPU: 00:00:02.948, GC gen0: 237, gen1: 3, gen2: 1
但是在最后一次更改之后,我得到了这个:
Real: 00:00:03.058, CPU: 00:00:03.057, GC gen0: 262, gen1: 262, gen2: 0
我很难弄清楚发生了什么。
更多的第 1 代垃圾收集意味着(?)有更多的长寿对象在第 0 代的垃圾收集中幸存下来 - 但为什么突然从 3 跳到 262?为什么第 0 代和第 1 代的垃圾回收次数相同?如果由于某种原因在代码更改后有更多长寿命的对象,我会期待这样的事情:
Real: 00:00:02.908, CPU: 00:00:02.948, GC gen0: 212, gen1: 54, gen2: 1
即垃圾收集对象的总数相似,但第一代更多。
还是我完全误解了这些数字(我在文档中找不到描述)?
更新
正如评论中所指出的,我完全误解了这些数字:它们是每一代执行的垃圾收集的数量,而不是对象的数量。
说了这么多,我更纳闷了:好像我的应用程序把内存置于这样一种状态,每次0代垃圾回收都会触发1代垃圾回收,我无法想象这种状态会是什么。我尝试了各种测试程序来复制这种行为,但没有运气。
我仍然必须按照评论和垫的答案中的建议尝试分析器。
更新 2
我按照评论中的建议尝试了 CLR 探查器 - 为此,我将 F# 脚本转换为程序并从探查器运行它。
我得到的报告与垃圾收集完全不同#time
:
- 第 0 代:279
- 第 1 代:5
- 第 2 代:2。
神秘 - 与独立程序相比,使用 FSI.exe 的副作用?错误#time
?