Java虚拟机如何运行Java字节码

 更新时间:2024年06月13日 15:10:26   作者:-红桃K  
这篇文章主要介绍了Java虚拟机如何运行Java字节码的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Java虚拟机如何运行Java字节码

以标准 JDK 中的 HotSpot 虚拟机为例,从虚拟机以及底层硬件两个角度来看Java 虚拟机具体是怎么运行 Java 字节码的。

虚拟机视角

从虚拟机视角来看,执行 Java 代码首先需要将它编译而成的 class 文件加载到 Java 虚拟机中。

加载后的 Java 类会被存放于方法区(Method Area)中。

实际运行时,虚拟机会执行方法区内的代码。

在运行过程中,每当调用进入一个 Java 方法,Java 虚拟机会在当前线程的 Java 方法栈中生成一个栈帧,用以存放局部变量以及字节码的操作数。

这个栈帧的大小是提前计算好的,而且 Java 虚拟机不要求栈帧在内存空间里连续分布。

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

硬件视角

从硬件视角来看,Java 字节码无法直接执行。因此,Java 虚拟机需要将字节码翻译成机器码。

在 HotSpot 里面,上述翻译过程有两种形式:

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

前者的优势在于无需等待编译,而后者的优势在于实际运行速度更快。

HotSpot 默认采用混合模式,综合了解释执行和即时编译两者的优点。

它会先解释执行字节码,而后将其中反复执行的热点代码,以方法为单位进行即时编译。

即时编译

即时编译建立在程序符合二八定律的假设上,也就是百分之二十的代码占据了百分之八十的计算资源。

对于占据大部分的不常用的代码,我们无需耗费时间将其编译成机器码,而是采取解释执行的方式运行;

另一方面,对于仅占据小部分的热点代码,我们则可以将其编译成机器码,以达到理想的运行速度。

为了满足不同用户场景的需要,HotSpot 内置了多个即时编译器:C1、C2 和 Graal。

Graal 是 Java 10 正式引入的实验性即时编译器,这里暂不做讨论。

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

  • C1 又叫做 Client 编译器,面向的是对启动性能有要求的客户端 GUI 程序,采用的优化手段相对简单,因此编译时间较短。
  • C2 又叫做 Server 编译器,面向的是对峰值性能有要求的服务器端程序,采用的优化手段相对复杂。

因此编译时间较长,但同时生成代码的执行效率较高。

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

为了不干扰应用的正常运行,HotSpot 的即时编译是放在额外的编译线程中进行的。

HotSpot 会根据 CPU 的数量设置编译线程的数目,并且按 1:2 的比例配置给 C1 及 C2 编译器。

在计算资源充足的情况下,字节码的解释执行和即时编译可同时进行。

编译完成后的机器码会在下次调用该方法时启用,以替换原本的解释执行。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java对象与json对象间的相互转换的方法

    java对象与json对象间的相互转换的方法

    本篇文章主要介绍了java对象与json对象间的相互转换的方法,详细介绍了json字符串和java对象相互转换,有兴趣的可以了解一下
    2017-01-01
  • 详解使用Spring3 实现用户登录以及权限认证

    详解使用Spring3 实现用户登录以及权限认证

    这篇文章主要介绍了详解使用Spring3 实现用户登录以及权限认证,这里整理了详细的代码,有需要的小伙伴可以参考下。
    2017-03-03
  • 解决mybatis-generator生成Mapper文件没有Selective结尾的问题

    解决mybatis-generator生成Mapper文件没有Selective结尾的问题

    这篇文章主要介绍了解决mybatis-generator生成Mapper文件没有Selective结尾的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • MyBatis延迟加载的处理方案

    MyBatis延迟加载的处理方案

    MyBatis 支持 延迟加载(Lazy Loading),允许在需要数据时才从数据库加载,而不是在查询结果第一次返回时就立即加载所有数据,延迟加载的核心思想是,将关联对象或集合的加载推迟到真正需要时才进行加载,本文给大家介绍了MyBatis延迟加载的处理方案
    2024-12-12
  • SpringBoot中properties,yml,yaml的区别及使用说明

    SpringBoot中properties,yml,yaml的区别及使用说明

    这篇文章主要介绍了SpringBoot中properties,yml,yaml的区别及使用说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • 在Spring中编写事务的介绍

    在Spring中编写事务的介绍

    今天小编就为大家分享一篇关于在Spring中编写事务的介绍,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • elasticsearch数据信息索引操作action support示例分析

    elasticsearch数据信息索引操作action support示例分析

    这篇文章主要为大家介绍了elasticsearch数据信息索引操作action support示例分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • IDEA导入geoserver项目的详细步骤及注意事项

    IDEA导入geoserver项目的详细步骤及注意事项

    由于GeoServer是基于Java开发的。因此在安装之前,必须确保安装了Java。本文给大家分享IDEA导入geoserver项目的详细步骤及注意事项,感兴趣的朋友一起看看吧
    2021-06-06
  • IntelliJ IDEA 代码运行时中文出现乱码问题及解决方法

    IntelliJ IDEA 代码运行时中文出现乱码问题及解决方法

    在我们刚接触到IDEA时,想美滋滋的敲一个“hello world”来问候这个世界,但难免会遇到这种问题乱码,这篇文章主要介绍了解决IntelliJ IDEA 代码运行时中文出现乱码问题,需要的朋友可以参考下
    2023-09-09
  • java的split方法使用示例

    java的split方法使用示例

    这篇文章主要介绍了java的split方法使用示例,需要的朋友可以参考下
    2014-04-04

最新评论