jvm-逃逸分析

本文介绍了逃逸分析在Java中的应用,包括对象是否逃逸的判断、同步省略、堆分配转为栈分配以及标量替换等优化技术。尽管存在技术成熟度和维护成本的问题,但逃逸分析能有效提升性能。
摘要由CSDN通过智能技术生成

1.逃逸分析

逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他地方中,称为方法逃逸。

public static StringBuffer craeteStringBuffer(String s1, String s2) {
    StringBuffer sb = new StringBuffer();
    sb.append(s1);
    sb.append(s2);
    return sb;   //对象逃逸
}

public static String createStringBuffer(String s1, String s2) {
    StringBuffer sb = new StringBuffer();
    sb.append(s1);
    sb.append(s2);
    return sb.toString(); //对象未逃逸
}

逃逸分析带来的好处:

  1. 同步省略。如果对象只能被一个线程访问到,那么对于这个对象的操作不考虑同步
  2. 堆分配转化为栈分配(重点)。若对象不会逃逸则可能是栈分配的候选而不是堆分配
  3. 分离对象或标量替换。有的对象可能不需要作为一个连续的内存结构存在也可以被访问到,那么对象的部分(或全部)可以不存储在内存,而是存储在CPU寄存器中。

-XX:+DoEscapeAnalysis:打开逃逸分析,JDK1.7默认配置

-XX:-DoEscapeAnalysis:关闭逃逸分析

1 同步省略

如果同步块所使用的锁对象经逃逸分析被证实只有一个线程访问,那么JIT编译器就会进行同步省略。也叫取消锁

public void f() {
    Object hollis = new Object();
    synchronized(hollis) {
        System.out.println(hollis);
    }
}
//因为hollis这个对象锁只在f()方法中使用,不会被其他线程访问所以进行同步省略
//JIT编译阶段优化后:

public void f() {
    Object hollis = new Object();
    System.out.println(hollis);
}

2 堆分配转为栈分配

当对象并没有逃逸出方法的话,那么可能被优化成栈上分配,这样就无须进行垃圾回收了

3 分离对象或标量

标量:无法再分解成更小的数据

聚合量:还可再分解的数据(java对象)

标量替换:JIT经过逃逸分析发现对象不被外界访问则将这个对象拆解成若干个成员变量进行替换。

标量替换好处:减少堆内存的分配

public static void main (String[] args) {
	alloc(); 
}
private static void alloc() {
	Point point = new Point (1.2);
}
class Point {
	private int X; 
	private int y;
}

//Point未被外接访问标量替换后

private static void alloc(){
    int x=1;
    int y=2;
}

-XX:+EliminateAllocations:开启了标量替换(默认打开),允许分配到栈上

逃逸分析小结

逃逸分析对代码的优化:

  1. 同步省略
  2. 栈上分配
  3. 对象标量替换

逃逸分析缺点:

  1. 技术不成熟
  2. 自身维护成本大,逃逸分析所消耗的内存不一定大于逃逸分析占用的内存(逃逸分析后发现对象都是逃逸的)

参考文章:https://segmentfault.com/a/1190000038262877

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值