字节码与执行

我们都知道01是计算机仅能识别的信号,不同的组合产生了不同的操作指令,这些机器指令面向的是CPU底层基础硬件
汇编语言使用助记符代替了对应的数字指令,而在JVM的字节码也设计了一套助记符代替对应的数字指令。
java实现跨平台的中间层就是以java字节码的形式。java所有的指令有200个左右,一个字节可以存储256种不同的指令信息,这样的字节称为字节码。xxx.class也称为java字节码。
字节码加载到虚拟机后有三种执行模式:解释执行[1],JIT编译执行[2]JTI和解释执行混合模式。混合模式的优势在于解释器在启动时解释执行,省去编译时间,而后通过热点代码分析,识别高频的方法调用、循环体和公共模块等,使用JIT编译技术将这些热点代码编译成机器码,直接交给CPU执行。

虚拟机加载java文件过程

我们写的java程序直接面向的是.java类型的文件,那么我们就需要将源文件转为字节码或者机器码的形式,虚拟机才可以读取执行。
获取到字节码后就需要请求虚拟机进行加载运行,这个过程包括:加载链接初始化三个阶段,其中链接又包括:验证,准备,解析三个小阶段,经过初始化,类才正式成为可执行的状态。

  • java文件转化为java字节码文件

    静态编译器经过词法解析语法解析语义解析后生成的字节码。
    词法分析:通过空格符分隔出单词、操作符等等信息传给下一步
    语法分析:根据接收的信息按照java语法生成一个语法树
    语义分析:检测关键字使用是否合理、类型是否匹配等等

  • 加载
    字节码.class需要加载到内存中才可以实例化类。这个阶段就需要类加载器对类文件进行加载,读取类文件产生二进制流后,转化为特定的数据结构,初步校验类常量池文件长度是否存在父类等等,然后创建对应类的Java.lang.class实例

  • 链接

    • 验证
      验证阶段是更严格的校验,final是否合规类型是否正确静态变量是否合理等等。

    • 准备
      准备阶段是为静态变量分配内存设置默认值

    • 解析
      解析类和方法,确保类于类之间引用的正确性,并会触发引用的未加载类的加载,完成内存结构的布局。
  • 初始化
    执行类构造器clinit方法,静态变量赋值。

类的加载是一个.class字节码文件实例化成.Class实例对象并进行相关初始化的过程。

在加载的过程中,JVM会初始化继承树上的所有没有被初始化的父类,并执行这个链路上的所有静态代码块,静态赋值语句等。

某些类使用时,也可以按需由类加载器进行加载。

以上就是一个java源文件在JVM执行过程。

类加载器

类加载器需要将java字节码加载到虚拟机中。

  • 启动类加载器(Bootstrap ClassLoader)
    所有类加载的祖师爷叫启动类加载器,启动类加载器是由C/C++实现的,所以在java中没有对应的对象,使用null指代。
    启动类加载器负责加载最重要、最基础的核心java类,如:jre/lib下jar中的类-Object、System、String等,除此外还加载由-Xbootclasspath参数指定的类。

  • 扩展类加载器(Extension ClassLoader)
    负责加载相对次重要的和常用的类,比如:jre/lib/ext的类文件,除此外还加载由java.ext.dirs系统变量指定的lei

  • 应用类加载器(Application ClassLoader)
    负责加载应用程序下的类,即环境变量指定的CLASSPATH下的类。

  • 自定义加载器
    按照自身需求制定相应的类加载器,加载一个加密的字节码时,使用自定义类加载器进行解密加载。

上面的几个类加载器都是在JDK9之前规定的,在JDK9后这种情况发生了一些变化。
除了启动类加载器外,其他的类加载器都规定为平台类加载器(paltform ClassLoader),除少数几个重要模块由启动类加载器加载外,其他都为平台类加载器进行加载。

类加载器是使用哪些加载器的呢??

  • 双亲委派模型
    当类加载器接收到一个类加载请求时,当前类加载器会将请求转发给父级类加载器,如果在该父类加载的类中不存在该类,则继续往父类加载器转发,直至到BootStrap启动类加载器,如果都加载不了,再回退给下一级类加载器去加载。
    双亲委派模式不具有强制约束,是java设计者推荐的类加载器实现方式。

自定义类加载器具体在那种需求下进行,主要就下面两种

  • 修改类加载方式
    根据实际情况按需动态加载

  • 防止源代码泄露
    在生成字节码是进行一定的加密,防止被代码篡改,在加载时就需要自定义的类加载器进行解密,还原成原来的字节码。

[1]:
[2]: