β

“java 代码是怎么运行的?”

Harries Blog™ 84 阅读
  • JRE 仅包含运行 java 程序的必须组件: Java 虚拟机以及 Java 核心类库等。
  • JDK(Java 开发 工具包)同样包含了 JRE,并且还附带了一系列开发,诊断工具。

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

    语法复杂,抽象程度高。

  • 转换具体操作

    主流思路:将 java 程序 转换为能被虚拟机识别的 java 字节码

  • 为什么叫 java 字节码?

    因为 java 字节码的操作码 (opcode) 被固定为一个字节。

  • 一个字节是多大?

  • 虚拟机的实现
  1. 硬件实现
  2. 软件 实现
  • 虚拟机的好处?
  1. 跨平台运行
  2. 带来了托管环境 (Managed Runtime) 。
  • 托管环境能够做什么?

    托管环境能够替我们处理 代码 中容易出错的部分。广为人知的 垃圾回收 和数组越界,动态类型, 安全 权限等等动态监测。

    使我们免为书写这些和业务逻辑无关的代码。

  • java 虚拟机具体是怎么运行字节码的?

    “java 代码是怎么运行的?”

  1. 编译 而成的 java 文件加载到 java 虚拟机中。
  2. 加载后的 java 类会被存放在方法区中 (Method Area) 中。实际运行时,虚拟机会执行方法区中的代码。
  3. 在运行过程中,每当进入一个 Java 方法,Java 虚拟机会在当前 线程 生成一个栈帧,用以存放局部变量以及字节码操作数。这个栈帧是提前计算好的,而且 java 虚拟机不需要栈帧在内存里连续分布。
  4. 当退出执行的方法时,不管时正常返回还是异常返回,java 虚拟机均会弹出当前栈帧,并将其舍弃。
  • 字节码怎么怎么 翻译 成机器码?

    两种方式:

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

    “java 代码是怎么运行的?”
    前者的优势在于无需等待编译,而后者的优势在于实际运行速度更快。
  • HotSpot 是怎样运行的?

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

  • Java 虚拟机的运行效率究竟是怎样的?

    理论上讲,即时编译后的 java 程序的执行效率是可能超过 C++ 程序的。这是因为与静态编译相比,即时编译拥有程序运行时的信息,并且能够根据这个信息作出相应的优化。

    举个例子:对于一个抽象方法,尽管它有许多个目标方法,但实际运行中他可能只调用其中一个。这个信息便可以被即时编译器所利用,来规避虚方法调用的开销,从而达到比静态编译的 C++ 程序更高的性能。

  • HotSpot 的多个即时编译器

    之所以引入多个即时编译器,是为了在编译 时间 和生成代码的执行效率之间进行取舍。

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

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

  • HotSpot 的解释编译和即时编译的分配?

    为了不干扰应用的正常运行,HotSpot 的即时编译是放在额外的编译线程中进行的。HotSpot 会根据 CPU 的数量设置编译线程的数目,并且按 1:2 的比例 配置 给 C1 及 C2 编译器。

    在计算资源充足的情况下,字节码的解释执行和即时编译可同时进行。编译完成后的机器码会在下次调用该方法时启用,以替换原本的解释执行。

  • 作业: 下载 asmtools.jar [2] ,并在命令行中运行下述指令(不包含提示符 $):

$ 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 vim Foo.java

➜  jvm javac Foo.java

➜  jvm java Foo

Hello,Java!

Hello,JVM

➜  jvm java -cp asmtools.jar org.openjdk.asmtools.jdis.Main Foo.class > Foo.jasm.1

➜  jvm awk 'NR==1,/iconst_1/{sub(/iconst_1/,"iconst_2")} 1' Foo.jasm.1 > Foo.jasm

➜  jvm java -cp asmtools.jar org.openjdk.asmtools.jasm.Main Foo.jasm

➜  jvm java Foo

Hello,Java!

原文
http ://heinika.coding.me/2018/07/28/jvm/java 代码是怎么运行的/

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。 PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处: Harries Blog™ » “java 代码是怎么运行的?”

作者:Harries Blog™
追心中的海,逐世界的梦
原文地址:“java 代码是怎么运行的?”, 感谢原作者分享。

发表评论