程序编译和代码优化

95 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情

一、自动装箱和封箱

  1. 示例讲解
 public static void main(String[] args) {
        Integer a=3;
        Integer b=3;
        Integer e=6;
        Long f=6L;
        Integer c=321;
        Integer d=321;
        System.out.println(a==b);       //true
        System.out.println(c==d);       //false
        System.out.println(e==(a+b));   //true
        System.out.println(e.equals((a+b)));   //true
        System.out.println(f==(a+b));   //true
        System.out.println(f.equals((a+b)));  //false
    }

"=="在不遇到算术运算的情况下不会自动拆箱,equals 不处理数据转型的关系。

当等于的两边都是包装器类型,比较的是对象,而如果其中一边是表达式,那么比较的就是值。

把一个基本类型赋值给 Object,他会自动进行装箱。

二、编译器和解释器

  1. 解释器(Interpreted Mode):快速的解释代码,省去编译的时间立即可以执行
  2. 编译器(Compiled Mode):可以编译成本地代码,执行的效率更高
  3. 使用-Xint 可以强制运行于解释模式
  4. 使用-Xcomp 可以强制运行于编译模式

解释执行节约内存,编译执行提升效率

image.png

5.程序中出现了空循环会被虚拟机优化消除掉

三、代码优化

如该代码:

 int value;

   final int get(){
       return value;
   }

   public void foo(){
       y=b.get();
       z=b.get();
       sum=y+z;
   }

优化后:

int value;

  final int get(){
      return value;
  }

  public void foo(){
      y=value;
      sum=y+y;
  }
1. 公共子表达式消除

举例说明:

int d=(c*b)*12+a+(a+b*c);

因为 cb 和 bc 结果是一样的,所以不用计算两次 可以被视为:

int d=E*12+a+(a+E);

根据代数化简优化,还能优化为

int d=E*13+a*2;
2. 数组边界检查消除

循环变量访问数组时,只要通过数据流分析循环变量的取值范围在区间之中,就可以去掉数组的上下界检查

2.1 隐式异常处理 如果有一个判断为空的表达式,值基本上都是不为空的。

if(foo!=null){

}else{
    throw new NullPointException();
}

可以优化成这样:

try{
    return foo;
}catch(Exception e){
    throw new NullPointException();
}

这样就减少了每次的 if 判断,如果 foo 基本都不是 null

3.方法内联

简单来说就是 a 方法调了 b 的方法,就直接把 b 方法复制出来放在 a 里面,避免方法之间的真实调用。

4.逃逸分析

这不是一种代码优化,而是为其他优化提供分析数据。 如果一个对象在方法中被定义后,除了被外部方法使用,还有可能作为入参被其他方法调用,这个叫做方法逃逸。 如果一个类变量被其他线程访问,这个叫线程逃逸。

如果这个对象不会逃逸,那么可以对这个对象做一些高效的优化:

  1. 栈上分配:

因为对象都是分配内存在堆上的,等不用了垃圾回收机制再去整理和回收,这些都会耗费时间。如果是分配在栈上,对象随着栈桢的出栈而销毁。减轻垃圾回收的压力。

  1. 标量替换:

    不能再拆散的数据叫标量,如基本类型和指针。如果一个对象不会被外部访问,那么他可以被拆为标量,当这个方法被执行的时候就可以不用创建对象,而改为创建这些标量,这样除了可以让这些数据在栈上外,还能进行其他优化

  2. 参数

    -XX:+DoEscapeAnalysis 开启逃逸分析

-XX:+PrintEscapeAnalysis 查看分析结果

-XX:+EliminateAllocations 开启标量替换

-XX:+PrintEliminateAllocations 查看标量替换

-XX:+EliminateLocks 开启同步消除