我们都知道,Java 创建的对象都是被分配到堆内存上,但是事实并不是这么绝对,通过对Java对象分配的过程分析,
可以知道有两个地方会导致Java中创建出来的对象并一定分别在所认为的堆上。
这两个点分别是Java中的逃逸分析和TLAB(Thread Local Allocation Buffer)线程私有的缓存区。
逃逸分析,是一种可以有效减少Java程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。
通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。
在计算机语言编译器优化原理中,逃逸分析是指分析指针动态范围的方法,它同编译器优化原理的指针分析和外形分析相关联。
当变量(或者对象)在方法中分配后,其指针有可能被返回或者被全局引用,这样就会被其他过程或者线程所引用,
这种现象称作指针(或者引用)的逃逸(Escape)。通俗点讲,如果一个对象的指针被多个方法或者线程引用时,
那么我们就称这个对象的指针发生了逃逸。
Java在Java SE 6u23以及以后的版本中支持并默认开启了逃逸分析的选项。Java的 HotSpot JIT编译器,能够在方法重载
或者动态加载代码的时候对代码进行逃逸分析,同时Java对象在堆上分配和内置线程的特点使得逃逸分析成Java的重要功能。
逃逸分析
定义: 分析对象的作用域
public class StackAllocation {
public StackAllocation allocation;
/** 方法返回对象发生逃逸 * @return
*/
public StackAllocation getAllocation() {
return allocation==null?new StackAllocation():allocation;
}
/**为成员属性赋值 发生逃逸 */
public void setAllocation(){
this.allocation = new StackAllocation();
}
/**对象的作用域仅在当前方法有效,没有逃逸**/
public void userStackAllocation() {
StackAllocation a = new StackAllocation();
}
/**引用成员变量值 会发生逃逸**/
public void useStackAllocation(){
StackAllocation allocation = getAllocation();
}
}