深入拆解 Java 虚拟机-打卡|01 | Java代码是怎么运行的?

news/2024/12/14 11:41:15/

文章目录

  • Java代码是怎么运行的?
    • 几个为什么
      • 为什么在虚拟机中运行?
      • Java 虚拟机具体又是怎样运行 Java 代码的呢?
      • Java虚拟机的运行效率怎么样?
    • 总结

Java代码是怎么运行的?

来来来,运行个"Hello word !“告诉我是怎么运行的?
看似这个很简单的问题,就像1+1=2一样,很是轻蔑,听老师讲当时陈景润研究了好长时间,也有说是罗素证明出来,还有说从来没有证明出来过,但不管怎么样这些由它去吧,运行"Hello word !” 就是麻雀虽小五脏俱全,一个简单流程,包括了所有的,我们继续回归Java是怎么运行的,我个人理解是这样的
编写代码–>JDK编译成字节码–>JVM解析字节码–>机器指令–>输出设备展示。
跟郑老师学习深入拆解JVM中,郑老师的开篇又是一个小故事,幽默但不偏离主题,说到海关问一个教授的问题,来引出对Java是什么运行的提问。
Java有很多种运行方式

  • 在工具中运行
  • 双击jar文件运行
  • 命令的方式运行
  • 甚至在网页中运行

均需满足有JRE的Java运行环境

再说说JRE
JRE(Java Runtime Environment)Java运行环境,包括Java程序的必须组件、Java虚拟机、以及核心类库等。JDK(Java Development Kit)Java开发工具和JRE的区别是,JDK包括JRE,JDK中还有开发、诊断工具,就是JDK包含JRE。

其中还提到的了C++的运行方式,C++是不需要额外的运行时,直接往往把代码直接编译成CPU所理解的代码,也就是机器码,所以C++没有很好的快平台性,Java就有跨平台性,因为JVM搞定了环境系统的差异。

几个为什么

  • 为什么 Java 要在虚拟机中运行呢?
  • Java 虚拟机具体又是怎样运行 Java 代码的呢?
  • 它的运行效率又如何呢?

Java是门高级语言,语法非常复杂,抽象程度很高,直接在机器上运行肯定是不可能的,运行起来是要过一番转换的。

语言的演变
二进制–>汇编语言–>高级语言

为什么在虚拟机中运行?

怎么转换呢?
Java源文件–>字节码–>在JVM上运行
因为字节码是底层的,是指令的操作码,被固定为一个字节,这也是字节码的由来。

JVM也可以由硬件实现,但更常见的是window、Linux、mac系统上提供软件实现的。这么做的好处是编译成字节码就直接在JVM上运行,也就是我们经常说的"一次编译,到处运行"。

JVM另外的一个好处是它带来了一个托管环境(Managed Runtime),能处理一些冗长容易出错的部分,其中最广为人知的就是内存管理和垃圾回收,这部分催生了一波垃圾回收调优的业务。嘿嘿,没有伤害就没有买卖。

托管环境还提供了诸如,数据越界、动态类型、安全权限等等的动态检测,使得我们免于书写这些无关的业务逻辑代码。都封装好了,我们只管用就好了,这让我想起来超市的模式,超市就是托管模式,商贩们提供卖东西的服务,就是正常的方法,其他的经营由超市管理人员来管理,商贩拿个摊位费。感觉就是编写代码的人,只管买卖东西,啥垃圾清扫啥的不需要顾客问,费用包含在商品里了,比喻虽然不恰当,但有相似之处 。

咱不熟悉X86咱也不明白这个如果你熟悉 X86 的话,你会发现这和段式内存管理中的代码段类似。而且,Java 虚拟机同样也在内存中划分出堆和栈来存储运行时数据。
Java 虚拟机还将栈细分为面向Java方法的Java方法栈,面向本地方法的本地方法栈(用C++ 写的native方法),存放线程执行位置信息的地方是PC寄存器,寄存器是存放指令集的数据。
Java虚拟机结构
在运行过程中,每当调用进入一个Java方法,虚拟机会在当前线程的Java方法栈中生成一个栈帧,用于存局部变量以及字节码的操作数,这个栈帧的大小是提前分配好的,而且Java虚拟机不要求栈帧在内存空间连续分布。

Java 虚拟机具体又是怎样运行 Java 代码的呢?

退出执行方法
不论正常返回,还是异常返回,Java虚拟机均会弹出当前线程的当前栈帧,并将之舍弃。
字节码执行
Java字节码是无法直接执行,Java虚拟机需要将字节码翻译成机器码。
怎么编译?
以HotSpot为例

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

两者的差别对比,前者的优势在于无需等待编译,而后者的优势在于速度更快。HotSpot默认采用的是混合编译的模式,综合了解释执行和即时编译两者的优点。先解释执行字节码,然后复制执行热点代码,以方法为单位进行即时编译。优点中西合璧的感觉,取其精华去其糟粕。

Java虚拟机的运行效率怎么样?

HotSpot采用多种技术来提升启动性能以及峰值性能,即时编译就是其中一种提升性能的方式。
二八定律也可以称为帕累托法则,事物的主要结果只取决于一小部分因素,这里也试用,20%的代码,占据了80%的计算资源。对大部分不常用的代码使用解释执行的方式进行,对于仅占据小部分热点的热点代码可以采用编译成机器码,以达到理想的运行速度。

理论上讲,即时编译后的 Java 程序的执行效率,是可能超过 C++ 程序的。这是因为与静态编译相比,即时编译拥有程序的运行时信息,并且能够根据这个信息做出相应的优化。据说交易系统的实现和编写都是使用C++,相对的C++速度较快,但最近出现了GoLang,据说很多大厂都将Java代码的功能使用Go进行重构,作为Java程序员心里老慌了,但学好JVM进行优化,我们将代码优化,可能依然是Go取代不了的。

虚拟方法居然是面向对象语言多态性的,对于一个虚方法调用,尽管它有很多个目标方法,但在实际运行过程中它可能只调用其中一个,这个信息便可以被即时编译器所利用,来规避虚方法调用的开销,从而达到比静态编译的 C++ 程序更高的性能。这点是之前从来没有接触过的,听君一席话胜读十年书的感觉油然而生。

HotSpot内置编译器

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

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

这编译来编译去的,影响正常应用程序运行吗?HotSpot的即时编译是放在额外的编译线程中进行的,这当然不影响应用进程。HotSpot会根据CPU的数量设置编译线程的数目,并按照1:2的比例给到C1和C2编译器。
如果计算资源充足,字节码解释执行和即时编译同时进行,编译后的机器码会在下次调用该方法时启用,来替换原来的解释行。

总结

java的运行经过几个阶段,编译、运行,运行在虚拟机上的优点是"一次编译,导出运行",的便捷性,虚拟机不仅提供字节码的运行环境和提供代码托管的环境,处理一些冗长且容易报错的事务,内存管理等。
Java虚拟机分为5个区,方法区、堆、PC寄存器、Java方法栈、本地方法栈,class字节码文件首先加载到虚拟机的方法区,才能在JVM中运行。

为了执行效率,HotSpot采用的混合执行的策略,首先采用的解释执行的方式,后续热点代码将采用即时编译进行以方法为单位的。


此文章为 4 月 Day18 学习笔记,内容来源于极客时间链接: 《深入拆解 Java 虚拟机》如果想学Java虚拟机的强烈推荐该课程!


http://www.ppmy.cn/news/47637.html

相关文章

C#内建接口:IComparable

目录 一、介绍 二、示例 注意:Array.Sort(people);调用了CompareTo方法 注意:WriteLine输出会调用ToString 三、笔试题实战 一、介绍 IComparable是一个接口,它定义了一个用于比较对象的方法CompareTo。在C#中,IComparable接…

第31天-贪心-第八章 ● 122.买卖股票的最佳时机II ● 55. 跳跃游戏 ● 45.跳跃游戏II

文章目录 1. 买卖股票的最佳时机2. 跳跃游戏3. 跳跃游戏 || 1. 买卖股票的最佳时机 - LeetCode链接 给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。 在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股…

PHP快速入门09-正则相关,附一定要学会的20个高频使用案例

文章目录 前言一、正则表达式介绍二、正则高频案例20个2.1 检查字符串是否以字母开头2.2 检查字符串是否以数字开头2.3 检查字符串是否包含特定字符2.4 检查字符串是否以特定字符结尾2.5 检查字符串是否为纯数字2.6 检查字符串是否为纯字母2.7 检查字符串是否为有效的电子邮件地…

C/C++每日一练(20230417)

目录 1. 字母异位词分组 🌟🌟 2. 计算右侧小于当前元素的个数 🌟🌟🌟 3. 加一 🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 J…

前端开发中性能优化之较少http请求(缓存策略)

1.实现减少http请求逻辑如下 定义了一个fetchData函数,用于发起HTTP请求并返回响应结果。函数的实现逻辑如下: 将请求参数对象params转换为字符串,作为缓存对象的键cacheKey。 如果缓存对象中已经有该请求参数对应的结果,直接返回…

实在智能获评十大数字经济风云企业,2022余杭数字经济“群英榜”发布

4月17日,经专家评审、公开投票,由中共杭州市余杭区委组织部(区委两新工委)、中共杭州市余杭区经济和信息化局委员会主办评选的2022年度余杭区数字经济“群英榜”正式公示。其中,实在智能成功获评十大数字经济风云企业之…

Linux 操作系统中应该掌握的知识

下面是我从业整理的一部分需要掌握的内容: 1. 基本命令行操作 基本命令行操作:包括文件管理、进程管理、用户权限等方面的基本命令行操作。 下面是文件管理、进程管理和用户权限相关的一些命令和内容: 1.1 文件管理 ls:显示当…

嵌入式Linux(5):物理地址到虚拟地址映射

文章目录 理论知识1、使能了MMU以后有什么好处呢?2、MMU非常复杂,那么我们如何完成物理地址到虚拟地址的转换呢?3、如何查看哪些物理地址被映射过了呢?实例(RK3568) 理论知识 在Linux上面如果想要操作硬件,需要先把物…