JVM进阶之字节码文件概述

Posted ProChick

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM进阶之字节码文件概述相关的知识,希望对你有一定的参考价值。

1.字节码文件的跨平台性

  • Java语言被称为跨平台的语言,当Java源代码成功编译成字节码后,如果想在不同的平台上面运行,则无须再次编译。但现如今很多语言,如:Python、php、 Perl、Ruby、 Lisp,几乎都具有跨平台的特性。

  • Java虚拟机被称为跨语言的平台,它只与“.class”这种特定的二进制文件有所关联,所以无论使用何种语言进行开发,只要我们将源代码正确编译成虚拟机所要求的这种二进制文件,那么它就可以在Java虚拟机上运行。

  • 要想使一个Java程序正确地运行在JVM中,Java源代码就必须要被编译为符合JVM规范的字节码。

    • 前端编译器的主要任务就是负责将符合Java语法规范的Java代码转换为符合JVM规范的字节码文件。

    • javac编译器是一种能够将Java源码编译为字节码的前端编译器,整个过程共经历4个步骤,分别是词法解析、语法解析、语义解析以及生成字节码。

2.前端编译器与后端编译器

  • 将Java源代码编译为字节码文件的工具就叫做前端编译器,但HotSpot虚拟机并没有强制要求前端编译器只能使用javac来编译,其实只要编译结果符合JVM规范即可。除了javac之外,还有一种被之前经常被用到的前端编译器,那就是内置在Eclipse中的ECJ (EclipseCompiler for Java)编译器。javac的特点是全量式编译,ECJ的特点是增量式编译,从编译质量来看它们大体一致,但ECJ的编译效率会比javac更加迅速和高效。
  • 在JVM中,把热点代码编译成本地机器指令的JIT编译器就叫做后端编译器。一个语言做出的程序是否高效,跟语言本身并没有太大关系,主要有关系的是编译器。Java语言最初没有编译器只有解释器,逐行执行的解释器效率较低,所以后期引入了JIT即时编译器,大大提升了执行效率。

3.从字节码角度分析程序

程序案例1

// 调用了Integer.valueOf()方法,从缓存数组中返回了一个Integer对象
Integer x = 5; 

// 定义了一个基本数据类型的5
int y = 5; 

// 此处虽然是引用类型和基本类型的比较,但是x会进行自动拆箱,最终其实就是x和y的值进行比较
System.out.println(x == y); // true

程序案例2

// Integer中存有一个缓存,范围为-128~127,从字节码中可以看出它们调用了Integer.valueOf方法

Integer i1 = 10;
Integer i2 = 10;
// 整数10在IntergerCache缓存的范围内,所以返回的是同一个对象
System.out.println(i1 == i2); // true

Integer i3 = 128;
Integer i4 = 128;
// 整数128不在IntergerCache缓存的范围内,所以返回的是新创建的对象
System.out.println(i3 == i4); // false

程序案例3

//此处实质是通过StringBuilder的append方法进行拼接操作,然后通过toString()方法进行new对象
String s1 = new String("hello") + new String("world");

//此处直接定义的是一个字符串常量
String s2 = "helloworld";

System.out.println(s1 == s2); // false

4.字节码文件解读的方式

  1. 使用Notepad++编辑工具,然后将字节码文件的内容转为16进制形式,或者使用Binary Viewer工具

  2. 使用JDK自带的javap命令工具

  3. 使用jclasslib bytecode viewer工具

    https://github.com/ingokegel/jclasslib

以上是关于JVM进阶之字节码文件概述的主要内容,如果未能解决你的问题,请参考以下文章

JVM进阶之字节码文件解析指令

JVM进阶之字节码指令解析(上篇)

JVM进阶之字节码指令解析(中篇)

JVM进阶之字节码文件结构

JVM进阶之路十二:字节码指令

JVM进阶之字节码指令解析(下篇)