面试官:Java虚拟机的内存分为哪几个区域?
我(微笑着):程序计数器、虚拟机栈、本地方法栈、堆、方法区
面试官:对象一般存放在哪个区域?
我:堆。
面试官:对象都存放在堆中吗?
我:是的。
面试官:你了解过逃逸分析吗?
我(皱了皱眉):是内存溢出吗?
面试官:不是的。
我(挠了挠头):不是很了解。
面试官:今天的面试先到这,回去等消息吧!
然后就没有然后了,不甘心的我开始了查找相关资料。
逃逸分析
逃逸分析(Escape Analysis)是一种确定对象的引用动态范围的分析方法,说人话就是:分析在程序的哪些地方可以访问到对象的引用。
当一个对象在方法中被分配时,该对象的引用可能逃逸到其它执行线程中,或是返回到方法的调用者。
如果一个方法中分配一个对象并返回一个该对象的引用针,那么该对象可能被访问到的地方就无法确定,此时对象的引用就发生了“逃逸”。
如果对象的引用存储在静态变量或者其它数据结构中,因为静态变量是可以在当前方法之外访问到,此时对象的引用也发生了“逃逸”。
逃逸分析确定某个对象的引用可以被访问的所有地方,以及确定能否保证对象的引用的生命周期只在当前进程或线程中。
逃逸状态
对象的逃逸状态一般分为三种:全局逃逸、参数逃逸、没有逃逸。
全局逃逸(GlobalEscape)
对象的引用逃出了方法或者线程。比如:对象的引用赋值给了一个静态变量,或者存储在一个已经逃逸的对象中, 或者对象的引用作为方法的返回值给了调用方法。
比如饿汉的单例模式:
package one.more;
public final class GlobalEscape {
// instance对象赋值给了一个静态变量,发生了全局逃逸
private static GlobalEscape instance = new GlobalEscape();
private GlobalEscape() {
}
public