JVM总结-虚拟机怎么执行字节码
1. JRE,JDK
JRE : java运行环境,Java 虚拟机+ Java 核心类库等。
JDK : JRE + 一系列开发、诊断工具。
2. java字节码
编译器将 Java 程序转换成虚拟机所能识别的指令序列,也称 Java 字节码。
3. 为什么java要在虚拟机里运行?
- 提供了可移植性
- java虚拟机提供垃圾回收等功能,使我们免于书写这些无关业务逻辑的代码。
4. Java 虚拟机具体是怎样运行 Java 字节码的?
从虚拟机视角来看
class 文件加载到 Java 虚拟机的方法区中。
实际运行时,虚拟机会执行方法区内的代码。Java 虚拟机在内存中划分出堆和栈来存储运行时数据。
Java 虚拟机将运行时内存区域划分为五个部分,分别为方法区、堆、PC 寄存器、Java 方法栈和本地方法栈。Java 程序编译而成的 class 文件,需要先加载至方法区中,方能在 Java 虚拟机中运行。
(JVM运行时数据区)
在运行过程中,每当调用进入一个 Java 方法,Java 虚拟机会在当前线程的 Java 方法栈中生成一个栈帧,用以存放局部变量以及字节码的操作数。这个栈帧的大小是提前计算好的,而且 Java 虚拟机不要求栈帧在内存空间里连续分布。
当退出当前执行的方法时,不管是正常返回还是异常返回,Java 虚拟机均会弹出当前线程的当前栈帧,并将之舍弃。
从硬件视角来看,Java 字节码无法直接执行。因此,Java 虚拟机需要将字节码翻译成机器码。
在 HotSpot 里面,上述翻译过程有两种形式:第一种是解释执行,即逐条将字节码翻译成机器码并执行;第二种是即时编译(Just-In-Time compilation,JIT),即将一个方法中包含的所有字节码编译成机器码后再执行。
前者的优势在于无需等待编译,而后者的优势在于实际运行速度更快。HotSpot 默认采用混合模式,综合了解释执行和即时编译两者的优点。它会先解释执行字节码,而后将其中反复执行的热点代码,以方法为单位进行即时编译。
5.Java 虚拟机的运行效率究竟是怎么样的?
HotSpot 采用了多种技术来提升启动性能以及峰值性能,刚刚提到的即时编译便是其中最重要的技术之一。
即时编译建立在程序符合二八定律的假设上,也就是百分之二十的代码占据了百分之八十的计算资源。
对于占据大部分的不常用的代码,我们无需耗费时间将其编译成机器码,而是采取解释执行的方式运行;另一方面,对于仅占据小部分的热点代码,我们则可以将其编译成机器码,以达到理想的运行速度。
在计算资源充足的情况下,字节码的解释执行和即时编译可同时进行。编译完成后的机器码会在下次调用该方法时启用,以替换原本的解释执行。
$ 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把boolean当做int来处理
flag = iconst_1 = true
awk把stackframe中的flag改为iconst_2
if(flag)比较时ifeq指令做是否为零判断,常数2仍为true,打印输出
if(true == flag)比较时if_cmpne做整数比较,iconst_1是否等于flag,比较失败,不再打印输出
JVM总结-虚拟机怎么执行字节码的更多相关文章
- 重读《深入理解Java虚拟机》五、虚拟机如何执行字节码?程序方法如何被执行?虚拟机执行引擎的工作机制
Class文件二进制字符流通过类加载器和虚拟机加载到内存(方法区)完成在内存上的布局和初始化后,虚拟机字节码执行引擎就可以执行相关代码实现程序所定义的功能.虚拟机执行引擎执行的对象是方法(均特指非本地 ...
- 【JDK命令行 一】手动编译Java源码与执行字节码命令合集(含外部依赖引用)
写作目标 记录常见的使用javac手动编译Java源码和java手动执行字节码的命令,一方面用于应对 Maven 和 Gradle 暂时无法使用的情况,临时生成class文件(使用自己的jar包):另 ...
- JVM(三):深入分析Java字节码-上
JVM(三):深入分析Java字节码-上 字节码文章分为上下两篇,上篇也就是本文主要讲述class文件存在的意义,以及其带来的益处.并分析其内在构成之一 ---字节码,而下篇则从指令集方面着手,讲解指 ...
- JVM学习笔记——类加载和字节码技术篇
JVM学习笔记--类加载和字节码技术篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的类加载和字节码技术部分 我们会分为以下几部分进行介绍: 类文件结构 字节码指令 编译期处理 类 ...
- lua执行字节码的过程介绍
前面一篇文章中介绍了lua给下面代码生成最终的字节码的整个过程,这次我们来看看lua vm执行这些字节码的过程. foo = "bar" local a, b = "a& ...
- JVM虚拟机(二):字节码执行引擎
运行时栈帧结构 栈帧是用于支持虚拟机进行方法调用和方法执行背后的数据结构,它也是虚拟机运行时数据区中的虚拟机栈的栈元素.栈帧存储了方法的局部变量表.操作数栈.动态链接.和方法返回地址等信息. ...
- [四] java虚拟机JVM编译器编译代码简介 字节码指令实例 代码到底编译成了什么形式
前言简介 前文已经对虚拟机进行过了简单的介绍,并且也对class文件结构,以及字节码指令进行了详尽的说明 想要了解JVM的运行机制,以及如何优化你的代码,你还需要了解一下,java编译器到底是 ...
- jvm系列四类加载与字节码技术
四.类加载与字节码技术 1.类文件结构 首先获得.class字节码文件 方法: 在文本文档里写入java代码(文件名与类名一致),将文件类型改为.java java终端中,执行javac X:...\ ...
- [置顶]
JVM层对jar包字节码加密
github https://github.com/sea-boat/ByteCodeEncrypt 需求 拿到的需求是要对某特定的jar包实现加密保护,jar包需要提供给外部使用,但核心逻辑部分需要 ...
随机推荐
- 八、springboot(五)配置定时器
1.修改启动类 @SpringBootApplication @EnableScheduling public class DemoApplication { public static void m ...
- 利用Jmeter批量数据库插入数据
1. 启动Jmeter 2. 添加 DBC Connection Configuration 右键线程组->添加->配置元件->JDBC Connection Configu ...
- 关键字:this、ref、out
Class1.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; usin ...
- 利用JavaFx开发RIA桌面应用-事件监听
1 事件监听 最近利用javaFX开发桌面客户端,碰到需要给各种UI控件添加事件监听,在这里做一个简单的小结,供日后参考. 2 分类处理 在JavaGUI 和Android中,事件通常通过实现list ...
- 银行卡所属公司判断 参考自https://blog.csdn.net/well2049/article/details/79429130
在网上找到了一个银行卡的验证,通过阿里的支付宝接口进行校验,能够准确识别是否存在,归属行,卡号类型是储蓄卡(DC)还是信用卡(CC). 接口api:需要传入的2个参数,卡号cardNo和cardBin ...
- NAND FLASH控制器
一.nand flash访问原理 地址空间概念 nand的编址 nand命令 命令,地址,数据 使用S3C2440的nand flash控制器访问nand flash 前几个编译出来的文件都小于4k ...
- 代码编辑器之sublime text
http://www.iplaysoft.com/sublimetext.html 1.特点: 中文乱码问题:另外,很多朋友反映表示打开中文会有乱码,其实是因为ST2本身只支持UTF-8编码,而我们常 ...
- JComboBox实现当前所选项功能和JFrame窗口释放资源的dispose()方法
JComboBox有一个 SelectedItem属性,所以使用getSelectedItem()就可以得到当前选中值. package ltb20180106; import javax.swing ...
- 黄聪:C#“多线程线程间操作无效: 从不是创建控件的线程访问它。”,跨线程修改控件属性解决方案
解决方案就是使用代理,在代理中调用主线程的方法来控制控件 /// <summary> /// 声明代理 /// </summary> delegate void SetText ...
- 测试教程网.unittest教程.1. 基本概念
From:http://www.testclass.net/pyunit/basic_concept/ unittest是python自带的单元测试框架,有时候又被称为”PyUnit”,是python ...