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

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

.NET

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

1.代码2.语言编译器编译3.IL4.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 程序需要进行预热。

总结

通过以上我们分别描述了 .NET 跟 JAVA 程序编译执行的过程。他们之间的区别在于 .NET 程序不管什么时候都是进行 JIT 编译,并且通过分层编译技术在首次执行速度跟性能之间找到了平衡。而 JAVA 虽然做为一门静态语言,但是它的代码一开始竟然是解释执行的(当然这是对 Hotspot JVM而言的,有的 JVM 未必是这样),在运行的时候才会对热点代码进行 JIT 编译优化代码。虽然大家实现的方式不同,但是殊途同归,都是通过对热点代码的二次编译实现了对程序的性能的优化。

参考

https://docs.microsoft.com/zh-cn/dotnet/standard/managed-execution-process
https://www.zhihu.com/question/37389356/answer/73820511

关注我的公众号一起玩转技术

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/299759.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

病毒加壳技术与脱壳杀毒方法解析

壳是什么?脱壳又是什么?这是很多经常感到迷惑和经常提出的问题,其实这个问题一点也不幼稚。当你想听说脱壳这个名词并试着去了解的时候,说明你已经在各个安全站点很有了一段日子了。下面,我们进入“壳”的世界吧。 一、…

java初学必看

今天又看到了这篇文章,不过今天看来,比当初有了更多的感受,对于初学者,的确是篇好文章,应该静下心来好好看看很多网友问我学习Java有没有什么捷径,我说"无他,唯手熟尔"。但是我却很愿意将自己学习…

在鹅厂,我作为一个Java 程序员每天都在摸鱼!!!

作为一名 在大、中、小微企业都待过 的 Java 开发者,今天和大家分享下自己在不同公司的工作日常和收获。包括一些个人积累的工作提升经验,以及一些 Java 学习的方法和资源。 先从我的第一份 Java 开发实习工作说起吧~ 实习生工作日常 我是在大二暑期开…

心中一万只草泥马在奔腾是种怎样的体验?| 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅(图源横店街道办主任,侵权删)

iOS工程中的info.plist文件的完整研究

原地址:http://blog.sina.com.cn/s/blog_947c4a9f0100zf41.html 们建立一个工程后,会在Supporting files下面看到一个"工程名-Info.plist"的文件,这个是对工程做一些运行期配置的文件,很重要,不能删除。 如果…

不会自动化UI测试?不会编程?没问题,会造句就行!

上次,我们介绍了用于Web应用程序自动化测试的工具Playwright for .NET。但是直接使用它来编写测试用例,代码比较凌乱,后期也不好维护。因此,我们利用SpecFlow让测试用例更好理解和维护。1.SpecFlow介绍SpecFlow是.Net平台下用于行…

鼠标手势识别 [Flash]

算法:演示:源代码:http://www.foxaweb.com/demos/mousegesture/mouse_gesture_v1_0.zip转载于:https://www.cnblogs.com/boringlamb/archive/2008/05/20/1203115.html

Java交流|面试最后一问:你有什么问题想问我吗?

尽管,我们之前做了这么多的面试准备,然而,最后这个90%可见的最后一问可能直接让你功亏一篑。这么厉害的最后一问:”你有什么问题想问我吗?“ 看似平淡无奇的问题,但是却蕴含着多方面的含义。这个问题表面上…

基于MapWinGis的开发探索(三)--改善缩放、渲染、显示文本

继续对MapWinGis进行研究探索,紧接上一篇文章。MapWinGis自身有很多功能,此篇主要也是基于其内在方法来写的。除了第二点显示文本是根据其源代码进行扩展的。原图:一、改善缩放功能上一版本放大缩小都必须点击下工具栏的放大、缩小。是鼠标处于缩放状态&…

T-SQL利用Row_Number函数实现分页

SQL: CREATE PROCEDURE PagingViewTest (currentPageIndex INT, --页序号pageSize INT, --页大小pageCount INT OUTPUT --返回值,总记录数 ) AS BEGIN--取总记录数 SELECT pageCountCOUNT(OrderID) FROM dbo.sale_Order; --利用CTE以提高执行效率 WITH Result AS (…

程序员没有女朋友的原因,我终于找到了!

全世界只有3.14 % 的人关注了青少年数学之旅程序员没有女朋友的原因▼程序员大脑里想的▼每天要学习太多语言,程序员太忙了▼女朋友 VS 编译器▼程序员sao起来,还需要女朋友吗?▼电脑才是程序员的女朋友▼互道晚安后,会不会偶遇在…

dotNet 5 中执行 Node.js

在低代码产品中为了扩展功能,我们在业务编排中会扩展代码块的功能,允许用户直接在界面中进行代码(Node.js、 Python)的编写,来实现取数或者赋值的一些功能。本文简单介绍下在 dotNET 5 中怎么样进行 Node.js 的调用以及…

求职学习笔记|并发编程知识点常见问题总结(一)

1. 什么是阻塞队列?阻塞队列的实现原理是什么? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。 这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可…

实验——Windows常用网络测试命令

<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />1.Ipconfig该命令可以检查网络接口配置。如果用户系统不能到达远程主机&#xff0c;而同一系统的其他主机可以到达&#xff0c;那么用该命令对这种故障进行判断是有必要的。当主机…

Protel中的快捷键使用(网上资源)

Protel中的快捷键使用&#xff08;网上资源&#xff09; 使用快捷键之前&#xff0c;将输入法切换至中文&#xff08;中国&#xff09;状态 Enter——选取或启动 Esc——放弃或取消F1——启动在线帮助窗 Tab——启动浮动图件的属性窗口Page Up——放大…

为什么会有蟑螂这种反人类的动物出现?

全世界只有3.14 % 的人关注了青少年数学之旅相信很多人都听过南北蟑螂的故事&#xff0c;即使是一个可以打死老虎的北方人在南方蟑螂面前也会惊慌失措。除此之外&#xff0c;我们日常生活里和蟑螂的故事还有很多&#xff0c;比如&#xff1a;当你打开灯的时候&#xff0c;会有一…

Ajax使用初步

Ajax定义为“Asynchronous JavaScript XML”的简称&#xff0c;也就是异步的JavaScript和XML处理。从原理上看&#xff0c;主要是Ajax可以通过调用HttpRequest实现与服务器的异步通讯&#xff0c;并最终在网页中实现丰富友好的用户界面Ajax使用初步&#xff0c;配置步骤1.把Aj…

WPF 如何流畅地滚动ScrollViewer

WPF开发者QQ群&#xff1a; 340500857 | 微信群 -> 进入公众号主页 加入组织欢迎转发、分享、点赞、在看&#xff0c;谢谢~。 前言看了看原生UWP的ScrollViewer&#xff0c;滑动很流畅(例如 开始菜单)&#xff0c;但是WPF自带的ScrollViewer滚动十分生硬..突发奇想&#x…

面试难点!常用算法技巧之“滑动窗口”

算法简介 滑动窗口&#xff0c;顾名思义&#xff0c;就是有一个大小可变的窗口&#xff0c;左右两端方向一致的向前滑动&#xff08;右端固定&#xff0c;左端滑动&#xff1b;左端固定&#xff0c;右端滑动&#xff09;。 可以想象成队列&#xff0c;一端在push元素&#xf…

回公司上班

回到公司上班了&#xff0c;悠闲的生活从此开始.....