怅然|java基础篇 - 虚拟机 - 逃逸分析

在java语言中 , 创建的对象主要分配在堆中 , 但是也有些对象不是分配在堆中 , 而是分配在栈中 。 虚拟机这样做的目的是为了提高程序运行的效率 。
java虚拟机会分析哪些对象发生了逃逸 , 哪些对象没有发生逃逸 , 针对没有发生逃逸的对象 , 则直接在栈上分配内存空间 , 这样做有2个好处:1、有效减少垃圾回收的次数 , 提升程序运行效率 。 2、因为栈上分配的内存会随着方法运行的结束而进行回收 , 因此可以降低内存空间的压力 。
到底哪些对象不会发生逃逸呢?不如直接看代码(重点看注释):
怅然|java基础篇 - 虚拟机 - 逃逸分析java代码
从上面程序代码可以看到 , testStr方法里面 , str对象是局部变量 , 也没有在方法中返回 , 因此是不会发生逃逸的 , 可以直接分配在栈上的 。
-XX:+DoEscapeAnalysis 代表的是开启逃逸分析进行优化 , -XX:-DoEscapeAnalysis 代表的是关闭逃逸分析(即:DoEscapeAnalysis 前面是加号 , 代表逃逸分析进行优化 , 如果DoEscapeAnalysis 前面是减号 , 则代表关闭逃逸分析) 。
可以通过一个具体的程序来看 , 逃逸分析能够提升程序的运行效率:
怅然|java基础篇 - 虚拟机 - 逃逸分析逃逸分析测试程序代码
在示例代码中 , test方法中 , 创建了1000万个int数组 , 这些数组全部是局部变量 , 也没有在方法中返回 。
首先我们关闭逃逸分析 , 虚拟机参数设置成-Xmx10m -Xms10m -XX:-DoEscapeAnalysis -XX:+PrintGC, 来运行程序 , 运行结果如下:
怅然|java基础篇 - 虚拟机 - 逃逸分析关闭逃逸分析运行结果
从运行的结果可以看到 , 关闭逃逸分析 , 对象在堆中创建 , 虚拟机执行了124次垃圾回收 , 程序运行的时间是97毫秒 。
其次我们开启逃逸分析 , 虚拟机参数设置成-Xmx10m -Xms10m -XX:+DoEscapeAnalysis -XX:+PrintGC , 来运行程序 , 运行结果如下:
怅然|java基础篇 - 虚拟机 - 逃逸分析开启逃逸分析运行结果
从运行结果可以看到 , 开启逃逸分析 , 对象在栈中创建 , 虚拟机执行了3次垃圾回收 , 程序的运行时间是13毫秒 。
从中我们可以看到 , 开启逃逸分析能够提升程序运行效率 , 原因是减少了垃圾回收的次数 , 对上述示例中的单线程尚且如此 , 更何况是多线程 。 java虚拟机默认是开启逃逸分析的 。
【怅然|java基础篇 - 虚拟机 - 逃逸分析】


    推荐阅读