C# 如何证明.NET CLR JIT每次运行只编译每个方法一次?
有人问C#是否每次都进行JIT编译,著名的Jon Skeet的回答是:“不,每个应用程序只编译一次”,只要我们谈论的是没有进行JIT编译的桌面应用程序 我想知道2009年的信息是否仍然正确,我想通过实验和调试,通过在抖动上设置断点,并使用WinDbg命令检查对象和方法,找出答案 到目前为止我的研究 我知道.NET内存布局在实际数据开始(地址a+4)之前会考虑每个对象的头(地址a-4)和方法表(地址a+0)。因此,每个对象都可能有不同的方法表,因此可能有不同的JITted方法 为什么我对这个说法的正确性有怀疑? 我们有一个关于并行编程的研讨会,培训师的一个说法是,每个线程的每个对象都会对方法进行JIT。这对我来说显然没有意义,我能够编写一个反例应用程序 不幸的是,出现了以下其他主题,我还想为此编写一个演示:C# 如何证明.NET CLR JIT每次运行只编译每个方法一次?,c#,.net,clr,windbg,jit,C#,.net,Clr,Windbg,Jit,有人问C#是否每次都进行JIT编译,著名的Jon Skeet的回答是:“不,每个应用程序只编译一次”,只要我们谈论的是没有进行JIT编译的桌面应用程序 我想知道2009年的信息是否仍然正确,我想通过实验和调试,通过在抖动上设置断点,并使用WinDbg命令检查对象和方法,找出答案 到目前为止我的研究 我知道.NET内存布局在实际数据开始(地址a+4)之前会考虑每个对象的头(地址a-4)和方法表(地址a+0)。因此,每个对象都可能有不同的方法表,因此可能有不同的JITted方法 为什么我对这个说法的
- 新的.NET框架
- 应用程序域
- 代码访问安全
是的,那没有任何意义。编译的范围是appdomains。我的第一个想法是,如果你对Jon Skeet关于旧问答的回答进行注释,以验证该信息是否仍然有效,那么你添加一个新的问答是毫无用处的……我不认为代码访问安全性会改变IL如何转化为真正的代码,我不认为新的框架改变了关于何时使用JIT的决定(但是引入了一个新的JIT编译器)。但你关于应用程序域的观点似乎提出了一个真正的新方面,但这一点尚未得到解决。我并不清楚为什么要证明这一点。这种说法肯定不是真的(闪避闪电),通用代码会被抖动编译多次。处理任何引用类型参数的一个副本和每个不同值类型参数的附加副本。当然,对于AppDomains,LoaderOptimization适用。有一些探查器回调告诉您抖动在做什么,ICorProfilerCallback::jitcomilationstarted()和ICorProfilerCallback4::rejitcomilationstarted()。除了Hans的注释外,从.NET 4.5开始,托管探查器可以请求运行时重新jitt方法(以便它可以以不同的方式对其进行检测)。还有一种情况是运行时可以使用ETW捕获.net Jit事件()。在配置文件中,将0x8008替换为0x8018以捕获Jit事件。现在您可以看到带有调用堆栈的加载程序、jit和异常数据。现在看看jit何时发生