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包需要提供给外部使用,但核心逻辑部分需要 ...
随机推荐
- TP5模型belongsTo和hasOne的区别
在使用tp5模型的ORM的时候出现belongsTo和hasOne都有表示一对一的关系,但是二者并不相同.以下举例说明两者的区别: 首先有user表 字段 id name password字段 然后有 ...
- MySQL程序只mysqlbinlog详解
mysqlbinlog命令详解 mysqlbinlog用于处理二进制的日志文件,如果想要查看这些日志文件的文本内容,就需要使用mysqlbinlog工具 用法: mysqlbinlog [option ...
- mysql二进制日志详解
一.什么是二进制日志 二进制日志主要记录mysql数据库的变化,二进制日志包含所有更新了数据或者潜在更新了数据(如没有匹配到任何行的delete语句),语句以时间的形式保存,描述了数据的更改.二进制日 ...
- 在Linux下安装JDK图文解析
参考自http://weixiaolu.iteye.com/blog/1401786 JDK官网下载:http://blog.csdn.net/chongxin1/article/details/70 ...
- ElasticSearch停止启动
1.查找ES进程 ps -ef | grep elastic 2.杀掉ES进程 kill -9 2382(进程号) 3.重启ES sh elasticsearch -d 注意:elasticsearc ...
- ArrayBlcokingQueue,LinkedBlockingQueue与Disruptor三种队列对比与分析
一.基本介绍 ArrayBlcokingQueue,LinkedBlockingQueue是jdk中内置的阻塞队列,网上对它们的分析已经很多,主要有以下几点: 1.底层实现机制不同,ArrayBlco ...
- ucos-iii串口用信号量及环形队列中断发送,用内建消息队列中断接收
串口发送部分代码: //通过信号量的方法发送数据 void usart1SendData(CPU_INT08U ch) { OS_ERR err; CPU_INT08U isTheFirstCh; O ...
- Gradle Java Web应用程序并在Tomcat上运行
1- 创建Gradle工程 打开 Eclipse ,在菜单中找到 File -> New -> Other…,在打开界面中选择 Gradle Project,如下图中所示 - 点击下一步( ...
- sql clr项目注意
1.如果引用了其他第三方的dll没有在系统里注册的话会报错,需要手工引用,引用的时候可能需要不安全的使用授权,如果没有权限则使用以下语句获取 alter database Class01New_Cac ...
- CentOS7切换到root用户和退回普通用户
切换成root用户: sudo su - 退出root用户并切换回普通用户: exit