Java开发前,都会做一件事情,安装编译Java代码的JDK环境,即配置Java运行环境。
JDK包含jre和其他一些工具包,jre包含运行java的虚拟机和一些核心类库等。
1:为什么java要在虚拟机中运行?
Java属于高级程序语言,语法复杂,抽象程度高。并不能直接在硬件上运行,所以(.java文件)需要经过编译器,编译成(.class文件)虚拟机能识别的指令序列,即Java字节码。Java虚拟机可以由硬件实现,但是在各个平台(windows,Linux)上已经提供了软件的实现。此时,程序一旦被编译为java字节码,就可以在多个平台上运行(“一次编译,到处运行")。不仅如此,虚拟机还提供了托管环境(Managed Runtime),托管环境能够代替我们处理代码带中容易出错的部分,最为常见的就是内存管理和垃圾回收,除此之外托管环境还提供了如:数组越界、动态类型、安全权限等动态监测,省去了我们书写与业务无关的代码。
2:Java虚拟机具体是怎么运行Java字节码的?
从虚拟机视角分析:执行Java代码首先需要将它编译而成的class文件加载到虚拟机中,加载后的Java类会被存放在方法区(Method Area)中,实际运行中,虚拟机会执行方法区内的代码。Java虚拟机会将内存划分出堆和栈来存储运行时的数据,而且Java虚拟机会将栈细分为面向Java的Java方法栈,面向本地方法(用C++写的native方法)的本地方法栈,以及存放各个线程的执行位置的PC寄存器。
在运行过程中,每调用一个Java方法,都会在当前线程的Java方法栈中生成一个栈帧,用以存放局部变量和字节码的操作数。这个栈帧是提前计算好的,而且Java虚拟机不要求栈帧在内存空间里连续分布。
当退出执行的方法时,不管是正常返回还是异常返回,Java虚拟就会弹出当前线程的当前栈帧,并将之舍弃。
从硬件角度分析:Java字节码无法直接执行,因此需要被虚拟机将字节码翻译成机器码。
以jdk中的HotSpot为例,上述翻译方式有两种;
- 解释执行:解释器将源程序逐句翻译的同时逐句执行。计算机执行起来速度慢,但是编译后的目标程序不依赖于特定的平台,通过在不同的平台上提供不同的解释器就可以跨平台执行。
- 编译执行:一次性把源程序编译成计算机能识别的目标程序。计算机执行起来速度非常快,但是编译后的目标程序只能在同一平台下运行。
前者的优势是无需等待,翻译后的目标源程序可以在不同平台的不同解释器下运行,但是计算机执行速度慢。后者优点是实际运行速度快,一次将程序翻译成机器码,但是依赖于指定平台。HotSpot默认采用混合模式,综合了解释执行和编译执行的优点,将热点代码采用编译执行,不常用代码采用解释执行。
3.Java虚拟机的运行效率究竟怎么样?
HotSpot内置了多个编译器,C1,C2和Graal;多个编译器有利于在编译时间和生成代码的执行效率之间做取舍。
C1被称为Client编译器,准对有启动性能要求的客户端程序,优化方法比较简单,编译速度较短。
C2被称为Server编译器,针对峰值性能有要求的服务器端程序,方法复杂,所以编译时间长,但是生成的代码执行效率很高。
从Java7开始,HotSpot采用分层编译的方式,热点方法首先被C1编译,热点中的热点进一步被C2编译,为了不干扰应用的正常运行,HotSpot 的即时编译是放
在额外的编译线程中进行的。HotSpot 会根据 CPU 的数量设置编译线程的数目,并且按 1:2 的比例配置给 C1 及 C2 编译器。
在计算资源充足的情况下,字节码的解释执行和即时编译可同时进行。编译完成后的机器码会在下次调用该方法时启用,以替换原本的解释执行。
口号鼓励:每天进步一点点,加油!奥利给~
来源:oschina
链接:https://my.oschina.net/pdg/blog/4871957