2021年7月29日星期四

关于 .NET 与 JAVA 在 JIT 编译上的一些差异

最近因为公司的一些原因,我也开始学习一些 JAVA 的知识。虽然我一直是以 .NET 语言为主的程序员,但是我并不排斥任何其它语言。在此并不讨论 JAVA .NET 的好坏,仅仅是对 .NET 跟 JAVA 程序的编译执行过程进行一些简单的介绍跟比较。因为有些内容还是超出自己原来的认知的,所以整理一下做个记录。

.NET

.NET 程序的执行过程大概分以下几个步骤:

  1. 代码
  2. 语言编译器编译
  3. IL
  4. JIT 编译
  5. 运行

.NET 平台的程序编译的时候是分多步的。当我们写好代码开始编译的时候需要选择一个合适的编译器比如csc 、vbc 。经过这一次编译之后我们的程序会被打包成 dll
或者 .exe 文件。这些 dll 里面其实包含的是 MSIL 。IL 做为一种中间语言,为跨平台提供了基础。当我们把这些文件复制到目标机器上需要真正运行的时候,JIT (just-in-time compilation)编译开始工作了。CLR 为我们在每个支持的平台上都实现了一个 JIT 编译器,当一个方法在第一次运行的时候,JIT 编译会把 IL 编译成目标机器的机器码,这样我们的程序才能真正运行。这也是为什么 .NET 程序第一次运行的时候会慢一点的原因。解决这个问题我们可以使用工具 Ngen.exe 在第一次运行前进行一次预编译,这样就可以提升 .NET 程序的启动速度。

分层编译

上面大概描述了 .NET 程序编译过程。但是 JIT 编译可能还有一些特性需要讲一下,比如分层编译。
分层编译是从 .NET core 2.1 开始引入的一个特性。我们的 IL 到机器码,需要 JIT 进行一次编译,这会影响 .NET 程序的第一次运行的速度。微软为了解决这个问题引入了分层编译。分层编译把 JIT 编译分成两次。当一个方法第一次被执行的时候,JIT 编译器会进行第一次快速编译,这次编译并不会进行特别的优化操作,追求的是编译的速度。当我们的程序运行一段时间后,CLR 会自动感知到频繁运行的代码,这些代码被称为热点代码。当出现热点代码的时候 JIT 编译器会重新进行一次优化编译来提高热点代码的执行效率,从而提高整个程序的性能。
通过 JIT 分层编译, .NET 程序很好的在编译速度跟性能之间找到了平衡。

JAVA

JAVA 程序的执行过程大概分以下几个步骤:

  1. 代码
  2. 语言编译器编译
  3. 字节码
  4. 解释/JIT编译
  5. 运行

下面说说 JAVA 程序的编译过程。
当我们编写好 JAVA 程序,想要执行的时候,跟 .NET 程序一样,同样会选择一个语言编译器来进行第一次编译。因为 JVM 语言有好多种,比如 JAVA ,kotlin ,所以同样会有多种语言编译器,比如 javac,kotlinc 等等。这里还是以标准的 JAVA 为例,在语言编译器编译完源代码后,会生成一堆 .class 的文件,这些文件包含的内容被称之为字节码。字节码的存在跟 MSIL 类似,同样为跨平台提供了一种很好的方案。只要为每个平台实现接口一致的 JVM , 让这些 JVM 来运行字节码就可以跨平台了。

解释执行

当我们真正要执行 JAVA 程序的时候,这些字节码会被 JVM 执行。JVM 执行的时候首先会在 CodeCache 内查找这个方法有没有编译好的机器代码,如果没有那么交给"解释执行器"来解释执行。所谓解释执行,就是将代码一行行的经过解释器进行翻译成机器码后让目标机器执行。但是这些翻译的产物并不会被记录下来,也就是说同样的代码每次执行的时候都需要解释器进行翻译。

JIT 编译

显然对于一些重复执行的方法解释器执行效率会很低。为了解决这个问题,设计 JVM 的工程师们想出了办法。以 Hotspot 为例,当程序经过一段时间的解释执行后,JVM 会记录这些方法的执行次数,当一些方法反复被执行的时候,JVM 会认为这些方法是热点代码。这时候 JVM 会对这些热点代码进行一次 JIT 编译,这次 JIT 编译还会根据运行时的 profile 进行优化。编译完成后把 JIT 编译的产物固定下来,存储在 CodeCache 中。这样当一个方法下次再次被执行的时候 JVM 会从 CodeCache 中直接读取机器码来执行。这样热点代码的执行效率就会大大的提供,这也是为啥有些 JAVA 程序需要进行预热。
......<p原文转载:http://www.shaoqun.com/a/902635.html

跨境电商:https://www.ikjzd.com/

dojo:https://www.ikjzd.com/w/2052

google correlate:https://www.ikjzd.com/w/1887

孙琦:https://www.ikjzd.com/w/1638


最近因为公司的一些原因,我也开始学习一些JAVA的知识。虽然我一直是以.NET语言为主的程序员,但是我并不排斥任何其它语言。在此并不讨论JAVA.NET的好坏,仅仅是对.NET跟JAVA程序的编译执行过程进行一些简单的介绍跟比较。因为有些内容还是超出自己原来的认知的,所以整理一下做个记录。.NET.NET程序的执行过程大概分以下几个步骤:代码语言编译器编译ILJIT编译运行.NET平台的程序编译的
这里是鸟儿的"天堂":http://www.30bags.com/a/223025.html
这里是青海!不去治不好,去过戒不掉!:http://www.30bags.com/a/270342.html
这里是人称"东方夏威夷"的中国最美海岛之一,隐藏着超多的绝世美景!:http://www.30bags.com/a/223605.html
这里是天下第一洞,它是我国造型最奇特的洞穴之一,你想来看看吗_织金洞:http://www.30bags.com/a/220354.html
女人口述被多P的滋味 一夜四次弄得我难受:http://lady.shaoqun.com/a/248084.html
女人喂男人吃私人部位 女人下面被吃有多爽:http://lady.shaoqun.com/m/a/247713.html
男朋友公车猛烈的一进一出 又硬又粗又长爽死我了:http://lady.shaoqun.com/m/a/247283.html
我想㖭你腿间的花 乖乖宝贝让我爽一下:http://www.30bags.com/m/a/249760.html
深圳8月有什么水果?采摘地推荐:http://www.30bags.com/a/530783.html
如梦之梦深圳官方购票渠道(在哪里买票):http://www.30bags.com/a/530784.html
深圳如梦之梦票价:http://www.30bags.com/a/530785.html
深圳8月有荔枝吗:http://www.30bags.com/a/530786.html