对象一定分配在堆中吗?有没有了解逃逸分析技术?

很多人在面试的时候都会被问到:堆和栈分别存储了什么?

很多人都知道 栈存储的是方法里面的局部变量。而堆存储的是数组或者对象。那对象一定就分配在堆中么?答案是不一定的。

问题就出现在“逃逸分析”上面?那么什么是逃逸分析呢?

逃逸分析(Escape Analysis) :是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。(是一种算法哦!)。通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围,从而决定是否要将这个对象分配到堆上。那什么叫逃逸呢? 逃逸通俗的来讲就是 如果一个对象的指针被多个方法或者线程引用。我们就说这个对象的指针发生了逃逸。

举个例子

public class EscapeAnalysisTest {


    //StringBuilder可能被其他方法改变,逃逸到了方法外部。
    public StringBuilder  escape(String a, String b) {
        StringBuilder str = new StringBuilder();
        str.append(a);
        str.append(b);
        return str;
    }

    //不直接返回StringBuffer,不发生逃逸
    public String notEscape(String a, String b) {
        StringBuilder str = new StringBuilder();
        str.append(a);
        str.append(b);
        return str.toString();
    }
}

发现没有,因为StringBuilder  可能会被其他方法调用,因此他可以逃逸到方法的外部 也就是escape方法中 定义的str可以逃逸,而方法notEscape中 其他人无法调用StringBuilder 的对象。

那逃逸分析有什么好处呢?

1.栈上分配,可以降低垃圾收集器运行的频率

2.同步消除,如果发现某个对象只能通过一个线程访问,那么在这个对象上的操作可以不需要同步

3.标量替换。把对象分解成一个个基本类型。并且内存分配不在分配到堆上,而是分配在栈上。这样的好处有,一、减少内存使用,因为不用生成对象头。二、程序内存回收效率高,并且GC频率也会减少。

扫描二维码关注公众号,回复: 13351186 查看本文章

猜你喜欢

转载自blog.csdn.net/Chen_leilei/article/details/110802568