JVM的逃逸分析
我们都知道Java中的对象默认都是分配到堆上,在调用栈中,只保存了对象的指针。当对象不再使用后,需要依靠GC来遍历引用树并回收内存。如果堆中对象数量太多,回收对象还有整理内存,都会会带来时间上的消耗,GC表示压力很大,然后影响性能。所以,在我们日常开发中,内存,时间都是相当的宝贵,该如何优化堆栈开销,是一个比较重要的问题。
在这里,我以逃逸分析角度聊聊JVM优化的那些事儿。
为什么“逃逸”
在计算机语言编译器优化原理中,逃逸分析是指分析指针动态范围的方法,它同编译器优化原理的指针分析和外形分析相关联。当变量(或者对象)在方法中分配后,其指针有可能被返回或者被全局引用,这样就会被其他方法或者线程所引用,这种现象称作指针(或者引用)的逃逸(Escape)。通俗点讲,如果一个对象的指针被多个方法或者线程引用时,那么我们就称这个对象的指针(或对象)的逃逸(Escape)。
网上有位博友这么形容逃逸,用了一段简单直接的代码,我觉得挺直截了当的,可以供参考:
public StringBuilder escapeDemo1(String a, String b) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(a);
stringBuilder.append(b);
return stringBuilder;
}
stringBuilder是在方法的内部变量,而此时它被直接返回,这样stringBuilder就有可能被其他地方的方法或参数所改变,这样它的作用域就不只是demo1了,虽然它是一个局部变量,但其发生了“逃逸”。
那么,我可以改一下代码:
public String escapeDemo2(String a, String b) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(a);
stringBuilder.append(b);
return stringBuilder.toString();
}
如此,就没有返回StringBuilder,而是toString(),那么StringBuilder没有从方法中直接脱离,就没有发生逃逸。
什么是逃逸分析
逃逸分析,是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。 逃逸分析(Escape Analysis)算是目前Java虚拟机中比较前沿的优化技术了。
逃逸分析的原理
Java本身的限制(对象只能分配到堆中),我可以这么理解了,为了减少临时对象在堆内分配的数量,我会在一个方法体内定义一个局部变量,并且该变量在方法执行过程中未发生逃逸,按照JVM调优机制,首先会在堆内存创建类的实例,然后将此对象的引用压入调用栈,继续执行,这是JVM优化前的方式。然后,我采用逃逸分析对JVM进行优化。即针对栈的重新分配方式,首先找出未逃逸的变量,将该变量直接存到栈里,无需进入堆,分配完成后,继续调用栈内执行,最后线程执行结束,栈空间被回收,局部变量也被回收了。如此操作,是优化前在堆中,优化后在栈中,从而减少了堆中对象的分配和销毁,从而优化性能。
逃逸的方式
方法逃逸:在一个方法体内,定义一个局部变量,而它可能被外部方法引用,比如作为调用参数传递给方法,或作为对象直接返回。或者,可以理解成对象跳出了方法。
线程逃逸:这个对象被其他线程访问到,比如赋值给了实例变量,并被其他线程访问到了。对象逃出了当前线程。
逃逸分析的好处
如果一个对象不会在方法体内,或线程内发生逃逸(或者说是通过逃逸分析后,使其未能发生逃逸)
1. 栈上分配
一般情况下,不会逃逸的对象所占空间比较大,如果能使用栈上的空间,那么大量的对象将随方法的结束而销毁,减轻了GC压力
2. 同步消除
如果你定义的类的方法上有同步锁,但在运行时,却只有一个线程在访问,此时逃逸分析后的机器码,会去掉同步锁运行。
3. 标量替换
Java虚拟机中的原始数据类型(int,long等数值类型以及reference类型等)都不能再进一步分解,它们可以称为标量。相对的,如果一个数据可以继续分解,那它称为聚合量,Java中最典型的聚合量是对象。如果逃逸分析证明一个对象不会被外部访问,并且这个对象是可分解的,那程序真正执行的时候将可能不创建这个对象,而改为直接创建它的若干个被这个方法使用到的成员变量来代替。拆散后的变量便可以被单独分析与优化,可以各自分别在栈帧或寄存器上分配空间,原本的对象就无需整体分配空间了。
开启设置
在JDK 6u23以上是默认开启,这里将设置重新明确一下:
强制开启:
-server -XX:+DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m
关闭逃逸分析:
-server -XX:-DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m
写在结尾
栈上的空间一般而言是非常小的,只能存放若干变化和小的数据结构,无法存储大容量数据。目前的实现都是采用不那么准确但是时间压力相对较小的算法来完成逃逸分析,这就可能导致效果不稳定。所以,逃逸分析的效果只能在特定场景下,满足高频和高数量的小容量的变量分配结构,才是合适的。
参考文章:https://www.jianshu.com/p/20bd2e9b1f03
http://www.importnew.com/27262.html
https://dzone.com/articles/escape-analysis-java-6-update
JVM的逃逸分析的更多相关文章
- JVM笔记-逃逸分析
参考: http://www.iteye.com/topic/473355http://blog.sina.com.cn/s/blog_4b6047bc01000avq.html 什么是逃逸分析(Es ...
- 小师妹学JVM之:逃逸分析和TLAB
目录 简介 逃逸分析和栈上分配 TLAB简介 TLAB详解 设置TLAB空间的大小 TLAB中大对象的分配 TLAB空间中的浪费 总结 简介 逃逸分析我们在JDK14中JVM的性能优化一文中已经讲过了 ...
- Java逃逸分析
Java逃逸分析 记录下看到的别人的博客内容,以后深入了解再详细写篇,加深下基础概念和印象! 一般来说,Java对象的创建,通常是在堆空间中分配内存,但是如果大量的临时对象也在堆空间创建的话,会导致性 ...
- JVM中启用逃逸分析
-XX:+DoEscapeAnalysis 逃逸分析优化JVM原理我们知道java对象是在堆里分配的,在调用栈中,只保存了对象的指针.当对象不再使用后,需要依靠GC来遍历引用树并回收内存,如果对象数量 ...
- JVM逃逸分析
开启逃逸分析: -server -XX:+DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m 关闭逃逸分析: -server -XX:-DoEsca ...
- Java之JVM逃逸分析
引言: 逃逸分析(Escape Analysis)是众多JVM技术中的一个使用不多的技术点,本文将通过一个实例来分析其使用场景. 概念 逃逸分析,是一种可以有效减少Java 程序中同步负载和内存堆分配 ...
- JVM 优化之逃逸分析
整理自 周志明<深入JVM> 1, 是JVM优化技术,它不是直接优化手段,而是为其它优化手段提供依据. 2,逃逸分析主要就是分析对象的动态作用域. 3,逃逸有两种:方法逃逸和线程逃逸. ...
- JVM中的逃逸分析
逃逸分析(Escape Analysis)是目前Java虚拟机中比较前沿的优化技术. 逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递 ...
- JVM之基础概念(运行时数据区域、TLAB、逃逸分析、分层编译)
运行时数据区域 JDK8 之前的内存布局 JDK8 之后的 JVM 内存布局 JDK8 之前,Hotspot 中方法区的实现是永久代(Perm),JDK8 开始使用元空间(Metaspace),以前永 ...
随机推荐
- python del 方法的使用
在Python 的自带函数中 del 函数是一个非常特殊但是又非常使用的函数 my_list = [1,2,3] my_dict = {"name":"lowman&qu ...
- 二,windows下安装memcached服务
window下安装memcached服务的流程如下: 1. 下载memcache的windows稳定版,解压放某个盘下面,比如在c:\memcached 2. 在终端(也即cmd命令界面)下输入 ‘c ...
- bootstrap 常用class(不定时更新)
1,字体居右 text-right 2,字体居中 text-center
- 为什么有监听socket和连接socket,为什么产生两个socket
为什么有监听socket和连接socket,为什么产生两个socket 先看一半的socket建立连接的双方的过程: 客户端: socket()---->创建出 active_socket_fd ...
- 了解ORACLE培训OCA-OCP-OCM课程表
了解ORACLE培训OCA-OCP-OCM课程表考试号: OCA 1Z0-007$125 Oracle Database 10g:SQL Fundamentals 本课程培养学生必要的SQ ...
- day 56 linux的安装python3 ,虚拟环境,mysql ,redis
1.1下载python源码包 网址:https://www.python.org/downloads/release/python-366/ 下载地址:https://www.python.org/f ...
- 【PaddlePaddle系列】CIFAR-10图像分类
前言 本文与前文对手写数字识别分类基本类似的,同样图像作为输入,类别作为输出.这里不同的是,不仅仅是使用简单的卷积神经网络加上全连接层的模型.卷积神经网络大火以来,发展出来许多经典的卷积神经网络模型, ...
- h5在线1v1客服|web在线客服系统|h5即时聊天
网上有很多环信.美恰之类的客服系统,最近也使用h5+css3+fontJs+swiper+wcPop等技术架构开发了一个在线客服(1v1沟通聊天),可以应用到在线临时聊天.在线咨询等情景.实现了消息. ...
- Spring中的BeanPostProcessor
一.何谓BeanProcessor BeanPostProcessor是SpringFramework里非常重要的核心接口之一,我先贴出一段源代码: /* * Copyright 2002-2015 ...
- android 使用lint + studio ,排查客户端无用string,drawable,layout资源
在项目中点击右键(或者菜单中的Analyze),在出现的右键菜单中有“Analyze” --> “run inspaction by Name ...”.在弹出的搜索窗口中输入想执行的检查类型, ...