在使用 Visual Studio 中的分析器来跟踪昂贵的函数时,我有时会看到大部分工作最终都在 [clr.dll] 中。这基本上相当于一个黑匣子,我想知道是否有办法追查为什么它在那里花了这么多时间。
我假设 clr.dll 处理诸如 JIT 编译、加载程序集和管理 appdomains、垃圾收集、反射等之类的事情。但是实际上很难判断是什么代码导致它花费了这么多时间。
很明显,除了运行时本身之外,还有其他一些代码导致它在 clr.dll 中花费了这么多时间,那么您如何追踪哪些代码有问题呢?
在使用 Visual Studio 中的分析器来跟踪昂贵的函数时,我有时会看到大部分工作最终都在 [clr.dll] 中。这基本上相当于一个黑匣子,我想知道是否有办法追查为什么它在那里花了这么多时间。
我假设 clr.dll 处理诸如 JIT 编译、加载程序集和管理 appdomains、垃圾收集、反射等之类的事情。但是实际上很难判断是什么代码导致它花费了这么多时间。
很明显,除了运行时本身之外,还有其他一些代码导致它在 clr.dll 中花费了这么多时间,那么您如何追踪哪些代码有问题呢?
你需要知道你的代码的哪一部分——你可以编辑和编译的代码,这是你唯一可以修复的代码——那部分代码占了相当大比例的时间使用。
知道clr.dll使用了很多时间是没有用的,除非您能分辨出代码的哪一部分负责它。
该信息在调用堆栈中。
如果你有一个方法,甚至是一行代码,它在堆栈上存在一定百分比的时间,例如 20%,那么它负责大约那个百分比的时间。如果你能以某种方式消除那行代码(或让它花费更少的时间),那么总时间的 20% 将变为零,或者几乎为零,给你一个 1.0/0.8 = 1.25 或 25% 的加速因子
那么如何找到这样的线条呢? 这是我使用的方法。 没有人声称它很漂亮,除非总的结果得到赞赏。如果重复应用,可能会有很大的加速因子。
根据我的经验,它可能在 GC 中。如果您使用 LINQ,几乎可以肯定它在 GC 中。我推荐 CLRProfiler 来追踪 Gen 0 垃圾邮件。