JVM(4) 字节码技术+运行期优化

字节码技术

1、类文件结构

   ca fe ba be 00 00 00 34 00 23 0a 00 06 00 15 09
  • 前4个字节为魔数:cafababe
  • 下来2个字节为小版本号:00 00
  • 下来2个字节为大版本号:00 34 —> 52 (对应jdk1.8, 45为jdk1.1)

2、字节码指令

使用 javap 工具反编译 class 文件:

   javap -v D:Demo.class

3、方法执行流程

在这里插入图片描述

  • 虚拟机栈:方法局部变量表+操作数栈+动态连接+返回地址
  • 局部变量表以slot为最小单位,存放方法参数和局部变量

4、异常处理

finally 中的字节码被复制了 3 份,分别放入 try 流程,catch 流程以及 catch 剩余的异常类型流程。
注意:虽然从字节码指令看来,每个块中都有 finally 块,但是 finally 块中的代码只会被执行一次

    public class Code_18_FinallyReturnTest {

        public static void main(String[] args) {
            int i = Code_18_FinallyReturnTest.test();
            // 结果为 20
            System.out.println(i);
        }

        public static int test() {
            int i;
            try {
                i = 10;
                return i;
            } finally {
                i = 20;
                return i;
            }
        }
    }
  • 如果在 finally 中出现了 return,会吞掉异常
  • finally 中有return,会覆盖try中的return
  • 字节码将异常信息显示在异常表

5、语法糖

  • 默认构造器

  • 自动拆装箱(jdk1.5之前不能自动)

  • 泛型擦除

  • 可变参数(public static void foo(String… args){})

  • foreach()自动转换为for(i=0; i<n;i++)或集合的迭代器Iterator遍历

  • switch

  • try-with-resources(省去在finally中关闭资源,且能保留关闭资源时的异常)

  • 方法重写时的桥接方法(子类返回值可以是父类返回值的子类–>jvm自动转换)

  • 匿名内部类(自动生成一个类)

运行期优化

1)即时编译

HotSpot是解释器与编译器并存的

  • 对于大部分的代码采取解释执行的方式运行;

  • 对于小部分运行频繁的热点代码,将其编译成机器码提高执行效率,以达到理想的运行速度。

分层编译
JVM 将执行状态分成了 5 个层次:

0层:解释执行,用解释器将字节码翻译为机器码
1层:使用 C1 即时编译器编译执行(不带 profiling)
2层:使用 C1 即时编译器编译执行(带基本的profiling)
3层:使用 C1 即时编译器编译执行(带完全的profiling)
4层:使用 C2 即时编译器编译执行

  • 解释器:
    • 将字节码解释为机器码,下次即使遇到相同的字节码,仍会执行重复的解释
    • 将字节码解释为针对所有平台都通用的机器码
  • 即时编译器
    • 将一些字节码编译为机器码,并存入 Code Cache,下次遇到相同的代码,直接执行,无需再编译
    • 根据平台类型,生成平台特定的机器码

执行效率上简单比较一下 Interpreter < C1(Client) < C2(Server)。

2)逃逸分析(Escape Analysis)

Java Hotspot 虚拟机分析新创建对象的动态作用域,并决定是否在 Java 堆上分配内存的一项技术。

当分析该对象不能逃逸到方法或线程外,进行以下优化:

  • 栈上分配(内存直接分配在栈上,对象随栈帧出栈销毁)
  • 同步消除
  • 标量替换(不创建对象,只创建用到的成员变量)

3)方法内联

如果JVM监测到一些小方法被频繁的执行,它会把方法的调用替换成方法体本身,如:

private int add4(int x1, int x2, int x3, int x4) { 
	//这里调用了add2方法
    return add2(x1, x2) + add2(x3, x4);  
}  
private int add2(int x1, int x2) {  
    return x1 + x2;  
}

方法调用被替换后

private int add4(int x1, int x2, int x3, int x4) {  
    //被替换为了方法本身
    return x1 + x2 + x3 + x4;  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值