0
点赞
收藏
分享

微信扫一扫

JVM之逃逸分析之标量替换

三次方 2022-05-01 阅读 58

标量替换
首先要明确数据分为聚合量和标量,标量是不可在继续分的,而聚合量是能够继续分的。如果逃逸分析证明一个对象不会被外访问或者引用,并且这个对象是可以分的,那么创建的时候就不会创建这个对象了,而改为使用若干个标量来替换它,这样是为了拆开以后便于标量可以在各个栈上进行分配了。

进行逃逸分析

//参数如下 -server -Xms100m -Xmx100m -XX:+UseParallelGC -XX:-DoEscapeAnalysis -XX:+UseTLAB -XX:+EliminateAllocations
public class EscapeAnalysisTest {
    static class User{
        byte[] bytes = new byte[1024*20];
    }
    public static void alloc(){
        User user = new User();
//        byte[] bytes = new byte[1024*20];这里首先关闭

    }

    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        for(int i = 0;i<100000;i++){
            alloc();
        }
        long endTime = System.currentTimeMillis();
        System.out.println(endTime-startTime+"ms");
        try {
            Thread.sleep(100000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

因为User是一个聚合量,所以执行的时候如果没有开启逃逸分析,就不会再栈上分配了,而改为在堆中分配。结果如下
在这里插入图片描述
然后开启逃逸分析 -XX:+DoEscapeAnalysis
执行结果如下
在这里插入图片描述
发现时间减少了
如果关闭标量替换 -XX:-EliminateAllocations会发现时间又变回来原来的关闭逃逸分析的时候了,所以可以证明这个对象是使用标量替换进行栈上分配的
在这里插入图片描述
假如把User换成 byte[]

//参数如下 -server -Xms100m -Xmx100m -XX:+UseParallelGC -XX:-DoEscapeAnalysis -XX:+UseTLAB -XX:+EliminateAllocations
public class EscapeAnalysisTest {
    static class User{
        byte[] bytes = new byte[1024*20];
    }
    public static void alloc(){
//        User user = new User();
        byte[] bytes = new byte[1024*20];

    }

    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        for(int i = 0;i<100000;i++){
            alloc();
        }
        long endTime = System.currentTimeMillis();
        System.out.println(endTime-startTime+"ms");
        try {
            Thread.sleep(100000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

结果如下
在这里插入图片描述
关闭逃逸分析 -XX:-DoEscapeAnalysis会发现还是一样的结果
在这里插入图片描述
因此对于不可再分的标量,其直接在栈上分配。

举报

相关推荐

0 条评论