必威体育Betway必威体育官网
当前位置:首页 > IT技术

Java代码是怎么运行的?

时间:2019-09-02 12:12:19来源:IT技术作者:seo实验室小编阅读:82次「手机版」
 

java代码

《深入拆解java虚拟机》学习笔记

专栏地址:http://gk.link/a/1018S

个人博客:http://laijianfeng.org

Java 和 C++ 在运行方式上的区别?

Java 代码有很多种不同的运行方式,比如在开发工具中运行、双击执行 jar 文件运行、在命令行中运行,甚至可以在网页中运行。

Java 的运行离不开 JRE(Java 运行时环境), JRE 仅包含运行 Java 程序的必需组件,包括 Java 虚拟机以及 Java 核心类库等。当然我们程序员更经常接触到的是 JDK(Java 开发工具包),包含了JRE,并且还附带了一系列开发、诊断工具

运行 C++ 代码则无需额外的运行时,往往把代码直接编译成 cpu 所能理解的机器码即可。

为什么 Java 要在虚拟机里运行?

Java 作为一门高级程序语言,它的语法非常复杂,抽象程度也很高。因此,直接在硬件上运行这种复杂的程序并不现实。

所以可以在 Java 代码与机器码之间加一层虚拟机,先将 Java 代码转换成 Java 字节码,最后才转换成机器码,降低复杂度。

Java hello world 字节码格式

Java字节码

Java 虚拟机的好处

  • 通过为各个平台linuxwindows、Mac os等)提供java虚拟机软件实现,在各个平台上都可以将java代码转换成字节码来运行Java(可移植性),达到 “一次编写、到处运行” 的目的

  • Java虚拟机为我们带来了一个托管环境(Managed runtime),可以替我们处理一些冗长而且容易出错的代码,最重要的譬如自动内存管理垃圾回收,同时还提供诸如数组越界动态类型安全权限等的动态检测,让我们可以专心的写业务代码

Java 虚拟机具体是怎样运行 Java 字节码的?

首先从虚拟机的角度来看:

  1. 首先将 Java 代码编译成的 class 文件
  2. 将 class 文件加载到 Java 虚拟机中(载入Java内存),加载后的 Java 类会被存放于方法区(Method Area)中
  3. 运行时,虚拟机执行方法区内的代码

Java虚拟机运行Java字节码的过程

Java 虚拟机会将栈细分为面向 Java 方法的 Java 方法栈,面向本地方法(用 C++ 写的 native 方法)的本地方法栈,以及存放各个线程执行位置的** PC 寄存器**。

本地方法,用关键字 native 修饰,基于JNI(Java Native Interface,Java本地接口),它允许 Java 代码和其他语言写的代码进行交互

在运行过程中,每当调用进入一个 Java 方法,Java 虚拟机会在当前线程的 Java 方法栈中生成

一个栈帧,用以存放局部变量以及字节码的操作数。(栈帧是提前计算好且不需连续分布)

当退出当前执行的方法时,不管是正常返回还是异常返回,Java 虚拟机均会弹出当前线程的当前栈帧,并将之舍弃。

Java 虚拟机将字节码翻译成机器码有两种形式:

  • 解释执行:即逐条将字节码翻译成机器码并执行;
  • 即时编译(Just-In-Time compilation,JIT),即将一个方法中包含的所有字节码编译成机器码后再执行。

Java虚拟机运行Java字节码的过程

解释执行的好处是无须等待编译,即时编译的好处是实际执行速度更快

HotSpot 默认采用混合模式,综合了解释执行和即时编译两者的优点,它会先解释执行字节码,然后将其中反复执行的热点代码以方法为单位进行即时编译

关于即时编译

即时编译主要是为了提高 Java 虚拟机的启动性能以及峰值性能,它建立在程序符合二八定律的假设上,也就是百分之二十的代码占据了百分之八十的计算资源

对于百分之八十(大部分)不常用的代码,我们无需耗费时间将其编译成机器码,而是采取解释执行的方式运行;对于百分之二十(小部分)的热点代码,我们则可以将其编译成机器码,以达到理想的运行速度

为了满足不同用户场景的需要(在编译时间和生成代码的执行效率之间进行取舍),HotSpot 内置了多个即时编译器:C1、C2 和 Graal

  • C1,又叫 Client 编译器,面向的是对启动性能有要求的客户端 GUI 程序,采用的优化手段相对简单,编译时间较短
  • C2,又叫 Server 编译器,面向的是对峰值性能有要求的服务器端程序,采用的优化手段相对复杂,编译时间较长,但同时生成代码的执行效率较高
  • Graal 是Java 10 正式引入的实验性即时编译器

从 Java 7 开始,HotSpot 默认采用分层编译的方式:热点方法首先会被 C1 编译,而后热点方法中的热点会进一步被 C2 编译。

小作业:观察两个条件判断语句的运行结果

通过观察两个条件判断语句的运行结果,来思考 Java 语言Java 虚拟机看待 boolean 类型的方式是否不同?

点击下载asmtools,并在命令行中运行下述指令

注:ASM 是一个 Java 字节码操控框架

$ echo '
public class Foo {
 public static void main(String[] args) {
  boolean flag = true;
  if (flag) System.out.println("Hello, Java!");
  if (flag == true) System.out.println("Hello, JVM!");
 }
}' > Foo.java
$ javac Foo.java
$ java Foo
$ java -cp /path/to/asmtools.jar org.openjdk.asmtools.jdis.Main Foo.class > Foo.jasm.1
$ awk 'NR==1,/iconst_1/{sub(/iconst_1/, "iconst_2")} 1' Foo.jasm.1 > Foo.jasm
$ java -cp /path/to/asmtools.jar org.openjdk.asmtools.jasm.Main Foo.jasm
$ java Foo

运行结果

结果分析:(来自评论区)

jvm 把 boolean 当做 int 来处理,flag = iconst_1 = true

awk 把 stackframe 中的 flag 改为 iconst_2

if(flag)比较时ifeq指令做是否为零判断,常数2仍为true,打印输出

if(true == flag)比较时if_cmpne做整数比较,iconst_1是否等于flag,比较失败,不再打

印输出

Hotspot 中的热点代码探测技术

怎样区分热点代码呢?主要有下面两种方法:

  • 基于采样的热点探测
  • 基于计数器的热点探测

计数器方法又可细分为方法调用计数器和汇编计数器

HotSpot的热点代码探测技术

  • 方法调用计数器 统计一个相对的执行频率,即一段时间内方法被调用的次数,当超过一定的时间限度,如果方法的调用次数仍然不足以让它提交给即时编译器,那这个方法的调用计数器就会被减少一半,这个过程称为方法调用计数器热度的衰减,而这段时间就称为方法统计的半衰周期,进行热度衰减的动作在虚拟机进行垃圾收集时顺便进行了。一般采用的都是基于计数器的热点探测,基于计数器的热点探测又有两个计数器,方法调用计数器,回边计数器,他们在C1和C2又有不同的阈值

  • 汇编计数器统计一个方法体重循环体代码执行的次数,在字节码中遇到控制流向后跳转的指令称为汇编,显然,建立汇编计数器的目的就是为了触发OSR编译。没有计数热度衰减的过程,因此这个计数器统计的就是该方法执行循环的绝对次数,当计数器溢出的时候它还会把方法计数器的值也调整到溢出的状态,这样下去在再次进入该方法的时候就会执行标准编译过程。


扫码购买可加入专栏进行学习,一起成长

极客时间.深入拆解Java虚拟机

相关阅读

滴滴黑名单功能开始试运行 你知道该怎么用吗?

A5创业网(公众号:iadmin5)10月18日消息,今天滴滴APP迎来了新功能——黑名单,目前黑名单功能已经开始试运行,那么你知道这个

TOR的原理————Tor的运行

   TOR是TheOnionRouter的缩写,直译就是洋葱路由。TOR官网上简单介绍了TOR的原理:TOR是一个三重代理,TOR客户端先与目录服务器通信

在命令行运行MonkeyRunner命令及通过MonkeyRunner运行

MonkeyRunner工具主要有三个类:MonkeyRunner、MonkeyDevice、MonkeyImage.可以直接使用一个代码文件运行monkeyrunner,抑或在交互式

计算机是怎样运行的?

一,概述 微机的工作过程就是不断地从内存中取出指令并执行指令的过程! 当开始运行程序时,首先应把第一条指令所在存储单元的地址赋

XCode iOS 12.3.1 (16F203) download 运行环境不支持

iOS DeviceSupport 12.3假的,暂时能用 https://github.com/XiaoHeHe1/iOS12.3- 参考:https://blog.csdn.net/qq_15509071/article/d

分享到:

栏目导航

推荐阅读

热门阅读