jvm:运行期优化
运行期优化
-
即时编译:
-
分层编译:将执行状态分成了5个层次;
-
0层,采用解释执行【interpreter】;
-
1层,使用C1即时编译器编译执行【不带profiling】;
-
2层,使用C1即时编译器编译执行【带基本profiling】;
-
3层,使用C1即时编译器编译执行【带完全profiling】;
-
4层,使用C2即时编译器编译执行;
profiling:在运行过程中收集一些程序执行状态的数据,例如,方法调用的次数,循环的次数;
效率:interpreter < C1 < C2
-
-
即时编译器【JIT】与解释器的区别:
- 解释器将字节码解释为机器码,下次遇到相同当字节码,也会执行重复的解释;
- JIT是将一些字节码编译为机器码,并存入 Code Cache,下次遇到相同代码,直接执行,无需要编译;
- 解释器,是针对所有平台,通用的机器码;
- JIT,会根据平台类型,生成平台特定的机械码【针对小部分热点代码,Hotspot】;
-
-
优化手段:逃逸分析
- 发现新建对象是否会被引用,当不存在引用的时候【那就是生产垃圾】,底层优化后,可能就不产生对象了;
-
方法内联:
- 当发现热点方法,而且长度不会太长,就会进行内联:把方法内代码拷贝,粘贴到调用的位置【节约一个栈帧】;
- 进一步,当发现有常数一直在进行运算的时候,能够进行常量折叠的优化,直接保存常量结果;
-
字段优化
-
对局部变量的访问速度要快于成员变量和静态变量,所有尽可能使用局部变量操作【当发生字段优化时,就会将成员变量先复制给局部变量,然后从局部变量获取】;
-
方法内联会影响字段优化;
//elements成员数组; for (int i=0, i < elements.length, i++) { dusum(elements[i]); } //字段优化,jvm优化; int[] local = this.elements; for (int i=0, i < local.length, i++) { dusum(local[i]); } //编译器优化,效果相同 for (int i : elements) { dusum(i); }
-
-
反射优化:
- 反射方法的调用,是通过本地方法的方法访问器进行调用;
- 当调用一共达到16次的时候,jvm会自动生成动态方法访问器,对于静态方法,其内部是使用 类名.方法的常规调用形式;

浙公网安备 33010602011771号