Java编译和解释,JIT即时编译

Java语言有两个最重要的特性,一个是所谓的“书写一次,到处运行”,另外一个是自动垃圾收集功能。前者通过将java程序编译成标准字节码而后通过JVM转为对应平台的机器码来屏蔽底层差异实现此特性。后者通过Java垃圾收集(Garbage Collector)回收分配内存使得开发人员不需要操心内存的分配和回收。

今天总结一下run anywhere 这个问题----Java里的编译和解释

计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序。

翻译的方式有两种,一个是编译,一个是解释。两种方式只是翻译的时间不同。

编译(compilation , compile):

通俗来讲,编译就是把高级语言变成计算机可以识别的二进制语言,计算机只认识1和0,编译程序把人们熟悉的语言换成二进制的。

编译型语言写的程序在执行之前,需要一个专门的编译过程,把程序编译成为机器语言的文件,比如exe文件以后要运行的话就不用重新翻译了,直接使用编译的结果就行了(exe文件)。

编译(compilation , compile)定义分为静态动态两种:

动态编译:指的是“在运行时进行编译”;
与之相对的是事前编译(ahead-of-time compilation,简称AOT),也叫静态编译

JIT编译 just-in-time compilation狭义来说是当某段代码即将第一次被执行时进行编译,因而叫“即时编译”。JIT编译是动态编译的一种特例。JIT编译一词后来被泛化,时常与动态编译等价;

解释:

解释则不同,解释性语言的程序不需要编译,省了道工序,解释性语言在运行程序的时候才翻译,比如解释性basic语言,专门有一个解释器能够直接执行basic程序,每个语句都是执行的时候才翻译。这样解释性语言每执行一次就要翻译一次,效率比较低。解释是一句一句的翻译。

因为翻译只做了一次,运行时不需要翻译,所以编译型语言的程序执行效率高,但也不能一概而论,部分解释型语言的解释器通过在运行时动态优化代码(比如Java动态编译器 JIT),甚至能够使解释型语言的性能超过编译型语言。

编译型与解释型,两者各有利弊。前者由于程序执行速度快,同等条件下对系统要求较低,因此像开发操作系统、大型应用程序、数据库系统时都采用它,像C/C++、Pascal/Object Pascal(Delphi)等都是编译语言,而一些网页脚本、服务器脚本及辅助开发接口这样的对速度要求不高、对不同系统平台间的兼容性有一定要求的程序则通常使用解释性语言,如JavaScript、VBScript、Perl、Python、Ruby、MATLAB 等等。

但随着硬件的升级和设计思想的变革,编译型和解释型语言越来越笼统,主要体现在一些新兴的高级语言上,而解释型语言的自身特点也使得编译器厂商愿意花费更多成本来优化解释器,解释型语言性能超过编译型语言也是必然的。

纯编译型语言的执行过程是:
源代码编译成二进制可执行性文件(比如.exe),然后运行的时候,直接运行这个可执行文件。不用再有编译的过程。这个exe换台电脑,直接就跑起来了。

java运行步骤:

.java文件->编译->.class文件,编译成.class字节码,
.class需要jvm解释,然后解释执行。

Java很特殊,Java程序需要编译但是没有直接编译成机器语言,即二进制语言,而是编译成字节码(.class)再用解释方式执行。

java程序编译以后的.class属于中间代码,并不是可执行程序exe,不是二进制文件,所以在执行的时候需要一个中介来解释中间代码,这既是java解释器,也就是所谓的java虚拟机(JVM),也叫JDK。

如果再重新运行这个Java程序的时候,就要再把.class文件再重新解释一遍!

因为java解释器采用生成与系统无关的字节代码指令技术。也就是说,在任何不同的操作系统上,只要正确安装了java运行系统,就有了编写调试java程序的平台,在分布式应用中,java的这个特点使同一个java程序能在不同的系统上运行,从而提高了软件生产效率。可移植性是跨平台特性的一个延伸,即具有了跨平台性,就保证了可移植性。java程序、java类库、java编译器、java系统都具有可移植性。

说了这么多,那java到底是编译型的还是解释型的 ?

首先,java需要编译,解释型语言不需要编译,然而java编译的结果又不是和其他编译型语言一样的二进制文件,而是.class文件。

从这一点上来看,java介于二者中间;

java编译完成以后,操作系统不能直接运行,而是需要java虚拟机解释执行class字节码文件。因此虚拟机将字节码程序与操作系统及硬件分开,使得java程序能在异构平台上执行。

从这一点上来看,java又属于解释型语言。

有很多JVM的实现比如Hotspot JVM 都提供了JIT(Just-In-Time)编译器,也就是通常说的动态编译器,JIT能够在运行时将热点代码编译成机器码,这也是一个编译的过程。

JIT编译也是在字节码基础上生成的

当虚拟机发现某个方法或代码块的运行特别频繁时,就会把这些代码认定为“热点代码”。为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优化,完成这个任务的编译器称为即时编译器(Just In Time Compiler,JIT编译器)。
需要注意的是:
这里JIT只是省去了本次Java程序运行之后,热点代码可以不用重新解释,
整个Java程序停了再重新启动,JIT编译的二进制就没了,要重新再编译
在这里插入图片描述

即时编译器并不是虚拟机必须的部分,Java虚拟机规范并没有规定Java虚拟机内必须要有即时编译器存在,更没有限定或指导即时编译器应该如何去实现。但是,即时编译器编译性能的好坏、代码优化程度的高低却是衡量一款商用虚拟机优秀与否的最关键的指标之一,它也是虚拟机中最核心且最能体现虚拟机技术水平的部分

具体的JIT参考: 传送门

所以如果严格来说,java属于半编译半解释型语言

猜你喜欢

转载自blog.csdn.net/qq_43778308/article/details/108574166