如何证明 .NET CLR JIT 每次运行只编译每个方法一次?

2024-05-20

There's 一个老问题 https://stackoverflow.com/questions/1255803/does-the-net-clr-jit-compile-every-method-every-time/1255832每次询问 C# 是否都是 JIT 编译时,著名的 Jon Skeet 的回答是:“不,每个应用程序只编译一次”,只要我们谈论的是非 NGEN 的桌面应用程序。

我想知道 2009 年的信息是否仍然正确,并且我想通过实验和调试来弄清楚这一点,可能是通过在 JITter 上放置断点并使用 WinDbg 命令来检查对象和方法。

到目前为止我的研究

我知道 .NET 内存布局在实际数据开始(地址 A+4)之前考虑每个对象的标头(地址 A-4)和方法表(地址 A+0)。因此,每个对象可能有不同的方法表,因此可能有不同的 JITted 方法。

为什么我怀疑这个说法的正确性?

我们举办了一个并行编程研讨会,培训师声称每个线程的每个对象的方法都是 JITted 的。这显然对我来说没有意义,我能够编写一个反例应用程序。

不幸的是,出现了以下其他主题,我也想为此编写一个演示:

  • 新的.NET框架
  • 应用领域
  • 代码访问安全

链接的答案是在 .NET 3.5 发布时编写的。从那时起它没有发生实质性变化,即它没有收到 .NET 4.0、4.6 和 4.6 的更新。

关于应用程序域,我个人的观点是,我可以卸载应用程序域,从而卸载程序集。如果卸载程序集,它就会消失,IL 代码也会随之消失。我认为保留被破坏的 IL 代码的本机代码没有多大好处。因此,我可以想象,创建应用程序域并再次加载程序集可能会导致再次对该方法进行 JIT 处理。

关于代码访问安全性,我不确定是JIT编译器根据当前权限考虑的还是运行时通过反射完成的。如果它是由 JIT 编译器完成的,则编译后的代码将会有所不同,具体取决于权限集。


JIT 的“设计原则”是编译一次方法(泛型方法的方法实例化)并重用相同的本机代码。当然,实现非常复杂,我将尝试在不影响准确性的情况下简化答案。对于从 .NET 2.0 到最新的 .NET 4.6 的所有运行时版本,答案都是相同的(我不知道 .NET 1.x,可能是相同的)。

运行时分析器回调和 ETW 事件的记录很少。当尝试 JIT 编译但不一定成功时,这两种情况都会发生。在三种情况下可能会发生这种情况:1-该方法无法满足某些安全要求,2-该方法的验证失败,3-无法分配内存来保存要发出的本机代码。因此,JIT 启动回调和事件可能会高估方法实际编译的次数。同样,JIT 完成回调和事件也不准确。在极少数情况下,他们可能会低估同一方法成功编译的次数。此时值得一提的是准确报告在进程的所有应用程序域中集体编译所有 IL 方法的次数。

对于特定于应用程序域的程序集,方法在每个应用程序域中单独编译。不存在共享(尽管有时在技术上是可行的)。对于与应用程序域无关的程序集,运行时attempts编译每个方法一次并与所有应用程序域共享本机代码。

如何证明 .NET CLR JIT 每个方法仅编译一次 跑步?

好吧,在某些情况下(例如使用后台 JIT 和其他极其微妙的情况时),方法可以在不执行的情况下进行编译。因此,说每个方法每次运行都会编译一次是不准确的。

您可以参考 CoreCLR JIT 源代码以获取更多信息(JIT 与 .NET Framework 4.5+ 中使用的 JIT 相同,但此答案适用于旧版本,因为 JIT 触发机制基本相同)。源代码就是证据。

每个线程的每个对象的方法都是 JITted

是的,这没有任何意义。编译范围是appdomains。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何证明 .NET CLR JIT 每次运行只编译每个方法一次? 的相关文章

  • 在路由mvc 4中添加公司名称

    我一直在尝试为 Facebook 等用户提供在 URL 中添加公司名称的选项 http localhost 50753 MyCompany Login 我尝试过不同的网址 但没有成功 routes MapRoute name Default
  • CSharpRepl emacs 集成?

    我碰巧知道莫诺CSharpRepl http www mono project com CsharpRepl 是否有 emacs csharp 模式使用它在一个窗口中运行 REPL 并像 python 模式一样在另一个窗口中编译 运行 C
  • 从模板切换传递的类型

    在 C 中是否可以检查传递给模板函数的类型 例如 template
  • C# 5 async/await 线程机制感觉不对?

    为什么让调用线程进入异步方法直到内部 等待 一旦调用异步方法就生成一个线程 这不是更干净吗 这样您就可以确定异步方法会立即返回 您不必担心在异步方法的早期阶段没有做任何昂贵的事情 我倾向于知道某个方法是否要在 我的 线程上执行代码 不管是堵
  • C# 开源 NMEA 解析器 [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找 C 开源 NMEA 解析器 嗯 我自己也不熟悉 但是一些快速搜索显示了一个代码项目 htt
  • 使用查询表达式对 List 进行排序

    我在使用 Linq 订购这样的结构时遇到问题 public class Person public int ID get set public List
  • 使用 C# 和 wpf 创建类似 Dock 的应用程序

    我需要创建一个与我们购买笔记本电脑时获得的应用程序类似的应用程序 仅当鼠标指针到达窗口顶部时它才可见 那么我怎样才能使用 C 4 0 来做到这一点呢 http www notebookcheck net uploads pics win2
  • 析构函数中的异步操作

    尝试在类析构函数中运行异步操作失败 这是代码 public class Executor public static void Main var c1 new Class1 c1 DoSomething public class Class
  • 使用具有抗锯齿功能的 C# 更改抗锯齿图像的背景颜色

    我有一个图像需要更改背景颜色 例如 将下面示例图像的背景更改为蓝色 然而 图像是抗锯齿的 所以我不能简单地用不同的颜色替换背景颜色 我尝试过的一种方法是创建第二个图像 仅作为背景 并更改其颜色并将两个图像合并为一个图像 但是这不起作用 因为
  • 引用/指针失效到底是什么?

    我找不到任何定义指针 引用无效在标准中 我问这个问题是因为我刚刚发现 C 11 禁止字符串的写时复制 COW 据我了解 如果应用了 COW 那么p仍然是一个有效的指针并且r以下命令后的有效参考 std string s abc std st
  • 英文日期差异

    接近重复 如何计算相对时间 https stackoverflow com questions 11 how do i calculate relative time 如何在 C 中计算某人的年龄 https stackoverflow c
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • 选择查询不适用于使用Parameters.AddWithValue 的参数

    C 中的以下查询不起作用 但我看不出问题所在 string Getquery select from user tbl where emp id emp id and birthdate birthdate cmdR Parameters
  • 在 C#.NET 中安全删除文件

    在我正在做的一个项目中 我想为用户提供 安全 删除文件的选项 例如 用随机位或 0 覆盖它 在 C NET 中是否有一种简单的方法可以做到这一点 效果如何 你可以调用系统内部删除 http technet microsoft com en
  • 为什么以下 C 程序会出现总线错误?

    我认为这是第一个失败的 strtok 调用 好久没写C了 有点不知所措 非常感谢 include
  • LINQ 中的“from..where”或“FirstOrDefault”

    传统上 当我尝试从数据库中获取用户的数据时 我使用了以下方法 在某种程度上 DbUsers curUser context DbUsers FirstOrDefault x gt x u LoginName id string name c
  • 来自 3rd 方库的链接器错误 LNK2019

    我正在将旧的 vc 6 0 应用程序移植到 vs2005 我收到以下链接器错误 我花了几天时间试图找到解决方案 错误LNK2019 无法解析的外部符号 imp 创建AwnService 52 在函数 public int thiscall
  • 如何使用placement new重新初始化该字段?

    我的课程包含字段 private OrderUpdate curOrderUpdate 我一遍又一遍地使用它 经常需要重新初始化 for int i 0 i lt entries size i auto entry entries i ne
  • 结构化绑定的用例有哪些?

    C 17 标准引入了新的结构化绑定 http en cppreference com w cpp language structured binding功能 最初是proposed http www open std org jtc1 sc
  • 为什么匹配模板类上的部分类模板特化与没有模板匹配的另一个部分特化不明确?

    这个问题可能很难用标题中的句子来描述 但这里有一个最小的例子 include

随机推荐