Java之JVM逃逸分析
引言: 逃逸分析(Escape Analysis)是众多JVM技术中的一个使用不多的技术点,本文将通过一个实例来分析其使用场景。
概念
逃逸分析,是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。
在计算机语言编译器优化原理中,逃逸分析是指分析指针动态范围的方法,它同编译器优化原理的指针分析和外形分析相关联。当变量(或者对象)在方法中分配后,其指针有可能被返回或者被全局引用,这样就会被其他过程或者线程所引用,这种现象称作指针(或者引用)的逃逸(Escape)。
Java在Java SE 6u23以及以后的版本中支持并默认开启了逃逸分析的选项。Java的 HotSpot JIT编译器,能够在方法重载或者动态加载代码的时候对代码进行逃逸分析,同时Java对象在堆上分配和内置线程的特点使得逃逸分析成Java的重要功能。
上面的这段话是我引用别人的一段话,文中使用了大量的专业术语,我总结一下它的意思就是:
通过逃逸分析来决定某些实例或者变量是否要在堆中进行分配,如果开启了逃逸分析,即可将这些变量直接在栈上进行分配,而非堆上进行分配。这些变量的指针可以被全局所引用,或者其其它线程所引用。
开启设置
默认的在JDK 6u23以上是默认开启,这里将设置重新明确一下:
强制开启:
-server -XX:+DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m
关闭逃逸分析:
-server -XX:-DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m
实例验证
代码:
public class OnStackTest {
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);
}
}
开启逃逸的运行结果:
未开启逃逸分析的运行结果:
分析一下,这里是将2个字节的数据循环分配1千万次,开启逃逸的运行时间为8milisecond, 而未开启则为956, 为未开启的将近1/120.
差异效果还是非常明显的…..
总结
栈上的空间一般而言是非常小的,只能存放若干变化和小的数据结构,大容量的存储结构是做不到。这里的例子是一个极端的千万次级的循环,突出了通过逃逸分析,让其直接从栈上分配,从而极大降低了GC的次数,提升了程序整体的执行效能。
所以,逃逸分析的效果只能在特定场景下,满足高频和高数量的容量比较小的变量分配结构,才可以生效。
———————- 无聊的分割线,终于到底了——————–
Java之JVM逃逸分析的更多相关文章
- 深入理解Java中的逃逸分析
在Java的编译体系中,一个Java的源代码文件变成计算机可执行的机器指令的过程中,需要经过两段编译,第一段是把.java文件转换成.class文件.第二段编译是把.class转换成机器指令的过程. ...
- java中的逃逸分析
逃逸分析 public static StringBuffer craeteStringBuffer(String s1, String s2) { StringBuffer sb = new Str ...
- JVM逃逸分析
开启逃逸分析: -server -XX:+DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m 关闭逃逸分析: -server -XX:-DoEsca ...
- java虚拟机的逃逸分析
逃逸分析作为其他优化手段提供依据的分析技术,其基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他方法中,称为方法逃逸.甚至还有可能被外部线程 ...
- 面试问我 Java 逃逸分析,瞬间被秒杀了。。
记得几年前有一次栈长去面试,问到了这么一个问题: Java中的对象都是在堆中分配吗?说明为什么! 当时我被问得一脸蒙逼,瞬间被秒杀得体无完肤,当时我压根就不知道他在考什么知识点,难道对象不是在堆中分配 ...
- [转]Java 逃逸分析
作者:栈长 公众号:Java技术栈 记得几年前有一次栈长去面试,问到了这么一个问题:Java中的对象都是在堆中分配吗?说明为什么! 当时我被问得一脸蒙逼,瞬间被秒杀得体无完肤,当时我压根就不知道他在 ...
- 逃逸分析(Escape Analysis)
一.什么是逃逸 逃逸是指在某个方法之内创建的对象,除了在方法体之内被引用之外,还在方法体之外被其它变量引用到:这样带来的后果是在该方法执行完毕之后,该方法中创建的对象将无法被GC回收,由于其被其它变量 ...
- JVM中启用逃逸分析
-XX:+DoEscapeAnalysis 逃逸分析优化JVM原理我们知道java对象是在堆里分配的,在调用栈中,只保存了对象的指针.当对象不再使用后,需要依靠GC来遍历引用树并回收内存,如果对象数量 ...
- JVM笔记-逃逸分析
参考: http://www.iteye.com/topic/473355http://blog.sina.com.cn/s/blog_4b6047bc01000avq.html 什么是逃逸分析(Es ...
随机推荐
- C++开学第一次作业(5.4)
开学第一次作业(5.4) 代码传送门 题目 Create a program that asks for the radius of a circle and prints the area of t ...
- MySQL中变量的用法——LeetCode 178. Rank Scores
Write a SQL query to rank scores. If there is a tie between two scores, both should have the same ra ...
- Fatal error compiling: java.lang.NoSuc hFieldError??
用了两天时间,试了各种方法,问题最终解决.是JDK的版本问题:Maven3.5不支持jdk-9.0.1,最后退回:jdk1.8.0_151,问题圆满解决!! [ERROR] Failed to exe ...
- CentOS 7 Fail2ban防暴力破解
1.安装 yum install epel-release -y yum install fail2ban fail2ban-systemd -y 2.配置 //新建配置 vim /etc/fail2 ...
- 关于C# get set的简单用法
关于C# get set的文章很多,但是笔者的这篇文章有它的特别之处,笔者用简单的语言把c# get set讲述的十分明了. C# get set释一:属性的访问器包含与获取(读取或计算)或设置(写) ...
- ETL增量处理总结
1 LOG表 1.1 思路 用log表记录业务库某表yw_tableA发生变化数据的主键.数据进入BI库目标表bi_tableA前,先根据log表记录的主键进行delete. 1.2 设计 1.2.1 ...
- springMVC数据回显
1.web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi=&qu ...
- Dokcer ELK
使用 docker 搭建 ELK 非常简单 docker run --name myes -d -p 9200:9200 -p 9300:9300 elasticsearch:2.4.4 运行 ...
- vue的seo方案 prerender-seo-plugin
利用vue cli 3.0安装脚手架.记住:勾选vue-router. 在vue.config.js里添加配置: 2, var path = require('path') 3, const Prer ...
- Kubernetes服务目录的设计
[编者的话]OpenShift 3.6新版本包括新的服务目录和服务中介技术预演版.它们是基于Kubernetes的孵化项目Kubernetes Service Catalog project.服务目录 ...