# 逃逸分析

//user的作用域超出了函数setUser的范围,是逃逸对象
//当函数结束调用时,不会自行销毁user
private User user;
public void setUser(){
    user = new User();
    user.setId(1);
    user.setName("blueStarWei");
}

//u只在函数内部生效,不是逃逸对象
//当函数调用结束,会自行销毁对象u
public void createUser(){
    User u = new User();
    u.setId(2);
    u.setName("JVM");
}

如果一个对象只在一个方法体中有效(线程私有),作用域被控制住了

那么JVM会优化分配策略,直接将对象分配在JVM虚拟机栈上,

这样直接在栈上分配和释放,效率更高

所以对象实例并不一定只存放在堆中

# 抄下其他人的demo

原文: https://www.cnblogs.com/BlueStarWei/p/9358757.html

package com.blueStarWei.templet;

public class AllotOnStack {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            alloc();
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    private static void alloc() {
        User user = new User();
        user.setId(1);
        user.setName("blueStarWei");
    }
}

JVM把堆设置小一些,发现并没有发生GC,就说明没有在堆中分配

如果JVM参数改成下方的,则会产生大量GC

//不使用逃逸分析
-server -Xmx15m -Xms15m -XX:DoEscapeAnalysis -XX:+PrintGC -XX:-UseTLAB -XX:+EliminateAllocations