栈上分配与逃逸分析
2019-03-18 15:04
106 查看
引言:栈上分配与逃逸分析是在JVM层面进行java性能优化的一个技巧,本文将深入解读其应用以及原理。
1. 什么是栈上分配?
栈上分配主要是指在Java程序的执行过程中,在方法体中声明的变量以及创建的对象,将直接从该线程所使用的栈中分配空间。 一般而言,创建对象都是从堆中来分配的,这里是指在栈上来分配空间给新创建的对象。
2. 什么是逃逸?
逃逸是指在某个方法之内创建的对象,除了在方法体之内被引用之外,还在方法体之外被其它变量引用到;这样带来的后果是在该方法执行完毕之后,该方法中创建的对象将无法被GC回收,由于其被其它变量引用。正常的方法调用中,方法体中创建的对象将在执行完毕之后,将回收其中创建的对象;故由于无法回收,即成为逃逸。
逃逸的几种情况:
static V global_v; public void a_method(){ V v=b_method(); c_method(); } public V b_method(){ V v=new V(); return v; } public void c_method(){ global_v=new V(); }
其中b_method方法内部生成的V对象的引用被返回给a_method方法内的变量v,c_method方法内生成的V对象被赋给了全局变量global_v。这两种场景都发生了(引用)逃逸。
3. 逃逸分析
在JDK 6之后支持对象的栈上分析和逃逸分析,在JDK 7中完全支持栈上分配对象。 其是否打开逃逸分析依赖于以下JVM的设置:
-XX:+DoEscapeAnalysis
- 栈上分配与逃逸分析的关系
进行逃逸分析之后,产生的后果是所有的对象都将由栈上分配,而非从JVM内存模型中的堆来分配。
5. 逃逸分析/栈上分配的优劣分析
优势表现在以下两个方面:
- 消除同步。线程同步的代价是相当高的,同步的后果是降低并发性和性能。逃逸分析可以判断出某个对象是否始终只被一个线程访问,如果只被一个线程访问,那么对该对象的同步操作就可以转化成没有同步保护的操作,这样就能大大提高并发程度和性能。
- 矢量替代。逃逸分析方法如果发现对象的内存存储结构不需要连续进行的话,就可以将对象的部分甚至全部都保存在CPU寄存器内,这样能大大提高访问速度。
package org.eds.homework.jvm; public class StackOnTest { public static void alloc() { byte[] b = new byte[2]; b[0] = 1; } public static void main(String[] args) { long b = System.currentTimeMillis(); for (int i = 0; i < 100000000; i++) { alloc(); } long e = System.currentTimeMillis(); System.out.println(e - b); } 20000 }
设置JVM的参数:
-server -Xmx10m -Xms10m -XX:+DoEscapeAnalysis -XX:+PrintGC
Eclipse的设置如下:
执行的结果如下: 未进行逃逸分析的设置:
-server -Xmx10m -Xms10m -XX:-DoEscapeAnalysis -XX:+PrintGC
执行的结果如下: 程序的结果分析: 在进行逃逸分析的运行结果中,只执行了9次就退出程序了。而未进行逃逸分析的结果是1360次,就是说未进行逃逸分析的代码可以执行更多的调用次数。换句话来讲,就是未进行逃逸分析的堆空间远大于进行逃逸分析后使用的栈空间,堆的空间大于栈,这就是根本原因。 7. 总结 栈上分配可以提升代码性能,降低在多线程情况下的锁使用,但是会受限于其空间的大小。 8. 参考资料
- https://www.geek-share.com/detail/2511330803.html
- http://www.cnblogs.com/gaiwen/archive/2013/09/24/3337835.html
相关文章推荐
- Java_JVM_逃逸分析技术_栈上分配_标量替换
- Jvm(1),逃逸分析和栈上分配
- Java中的逃逸分析和TLAB以及Java对象分配
- JVM的栈上分配与逃逸分析(Escape Analysis)
- 逃逸分析与栈上分配
- Java中的逃逸分析和TLAB以及Java对象分配
- (九)栈上分配与逃逸分析
- 内存分配--栈上分配(逃逸分析)
- Java中的逃逸分析和TLAB以及Java对象分配
- 频繁分配释放内存导致的性能问题的分析
- 一句话补充逃逸分析
- IP address 分配异常慢问题分析 推荐
- Java即时编译和逃逸分析
- 从源码角度分析Android中UID与GID的分配
- Linux中的内存分配和释放之bootmam_init()函数分析
- JVM优化之逃逸分析(Escape Analysis)
- java内存分配分析
- Linux中的内存分配和释放之free_bootmem()函数分析
- ECSHOP后台权限分配原理分析
- Linux开发心得总结9 - Linux中的内存分配和释放之kmem_cache_alloc()函数分析