随记----逃逸分析:代码优化---20200518

14 篇文章 0 订阅

JVM–堆--笔记
使用逃逸分析,编译器可对代码做如下优化:

  1. 栈上分配:将堆分配转化为栈分配,如果一个对象在子程序中被分配,要使指向该对象的指针永远不会逃逸,对象可能是栈分配的候选,而不是堆分配。
  2. 同步省略。如果一个对象被发现只能从一个线程被访问到,那么对于这个对象的操作可以不考虑同步。
  3. 分配对象或标量替换:有的对象可能不需要作为一个连续的内存结构存在也可以被访问到,那么对象的部分或全部可以不存储在内存,而是存储在CPU寄存器中。

栈上分配

-XX:-DoEscapeAnalysis与-XX:+DoEscapeAnalysis 做对比,后者运行时间更短,而且没有进行GC

package learn.jvm.simple.heap;
/*
     栈上分配测试
     -Xmx1G -Xms1G -XX:-DoEscapeAnalysis -XX:+PrintGCDetails

与-XX:+DoEscapeAnalysis 做对比,后者运行时间更短,而且没有进行GC
 */
public class StackAllocation {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            alloc();
        }
        long end = System.currentTimeMillis();
        System.out.println((end - start) + " ms");
        try {
            Thread.sleep(10000000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static void alloc() {
        User user = new User();
    }
    static  class User{

    }
}

同步省略

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

hollis只被一个线程使用,synchronized会被省略。

分配对象或标量替换

  • 标量(Scalar)是指一个无法再分解为更小的数据的数据。Java中的原始数据类型就是标量。
  • 相对的,那些还可以再分解的数据叫做聚合量(Aggregate),Java中的对象就是聚合量,因为它可以分解为其它聚合量和标量。
  • 在JIT阶段,如果经过逃逸分析,发现一个对象不会被外界访问的话,那么经过JIT优化,就会把这个对象拆解为若干个其中包含的若干个成员变量来代替,这个过程就叫标量替换
public static void main(String[] args) {
        alloc();
    }
    private static void alloc() {
        Point point = new Point(1,2);
        System.out.println("point.x=" + point.x + ";point.y=" + point.y);
    }
    static class Point{
        private int x;
        private int y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

经过标量替换后变成:

private static void alloc() {
        int x=1;
        int y=2;
        System.out.println("point.x=" + x + ";point.y=" + y);
    }

这样可以减少堆内存的使用。

-XX:+EliminateAllocations开启标量替换(默认打开),允许将对象打散分配在栈上。

小结

逃逸分析技术并不成熟,但它也是即时编译器优化技术中一个十分重要的手段。
无法保证进行逃逸分析的性能一定高于不进行逃逸分析的性能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值