美文网首页
JVM内存逃逸与栈上分配,程序员必须掌握的知识

JVM内存逃逸与栈上分配,程序员必须掌握的知识

作者: Sunny捏 | 来源:发表于2020-06-18 15:19 被阅读0次
逃逸分析
内存逃逸主要是对象的动态作用域的改变而引起的,故而内存逃逸的分析就是分析对象的动态作用域。
发生逃逸行为的情况分为两种:方法逃逸和线程逃逸
方法逃逸
当方法创建了一个对象之后,这个对象被外部方法所调用,这个时候方法运行结束要进行GC时,本该方法的对象被回收,却发现该对象还存活着,没法回收,则称为 "方法逃逸"
简单来说:就是当前方法创建的对象,本该是当前方法的栈帧所管理,却被调用方所使用,可以称之为内存逃逸

下图中,可以看到直接将User对象返回出去,这样这个User对象有可能会被其他地方所改变,这样他的作用域就不只是在方法内部了,这样就是逃逸到方法外部了

那怎么样才能够不让方法逃逸呢?很简单,就不返回User对象即可,看下图

线程逃逸
上面的例子,直接将对象进行返回出去,该对象很有可能被外部线程所访问,如:赋值给变量等等 则称为 "线程逃逸
栈上分配

如果能够证明一个对象,不会进行逃逸到方法或线程外的话,则可以对该变量进行优化

当我们创建一个对象的时候,会立马想到该对象是会存储到堆空间中的,而垃圾回收机制会在堆空间中回收不再使用的对象,但是筛选可回收对象,还有整理对象都需要消耗时间,如果能够通过逃逸分析确定某些对象不会逃出到方法外的话,那么就可以直接让这个对象在栈空间分配内存,这样该对象会随着方法的执行完毕自动进行销毁

简单来说:比如说,我上一篇文章有写到,一个方法对应一个栈帧,而我的对象是在当前的栈帧中所管理的,并非逃逸到方法外,所以创建的对象是在栈中,而非堆中,所以称为 "栈上分配"
同步消除
线程同步本身比较耗时,若确定了一个变量不会逃逸出线程,无法被其他线程访问到,那这个变量的读写就不会存在竞争,则可以消除对该对象的同步锁
标量替换
1、标量是指不可分割的量,如java中基本数据类型和reference类型,都不能再进一步分解,他们就可以称为标量。
2、若一个数据可以继续分解,那就称之为聚合量,而对象就是典型的聚合量。
3、若逃逸分析证明一个对象不会逃逸出方法,不会被外部访问,并且这个对象是可以被分解的,那程序在真正执行的时候可能不创建这个对象,而是直接创建这个对象分解后的标量来代替。这样就无需在对对象分配空间了,只在栈上为分解出的变量分配内存即可。

注意:

逃逸分析是比较耗时的,所以性能未必提升很多,因为其耗时性,采用的算法都是不那么准确但是时间压力相对较小的算法来完成的,这就可能导致效果不稳定,要慎用。
由于HotSpot虚拟机目前的实现方法导致栈上分配实现起来比较复杂,所以HotSpot虚拟机中暂时还没有这项优化。

相关JVM参数

-XX:+DoEscapeAnalysis 开启逃逸分析、
-XX:+PrintEscapeAnalysis 开启逃逸分析后,可通过此参数查看分析结果。
-XX:+EliminateAllocations 开启标量替换
-XX:+EliminateLocks 开启同步消除
-XX:+PrintEliminateAllocations 开启标量替换后,查看标量替换情况。

相关文章

  • JVM内存逃逸与栈上分配,程序员必须掌握的知识

    逃逸分析 方法逃逸 下图中,可以看到直接将User对象返回出去,这样这个User对象有可能会被其他地方所改变,这样...

  • JVM的逃逸分析

    对象一定分配在堆中吗? JVM通过逃逸分析,那些逃不出方法的对象会在栈上分配。 什么是逃逸分析? EscapeAn...

  • 小师妹学JVM之:逃逸分析和TLAB

    简介 逃逸分析我们在JDK14中JVM的性能优化一文中已经讲过了,逃逸分析的结果就是JVM会在栈上分配对象,从而提...

  • java对象分配过程

    1.编译器通过逃逸分析判断对象是在栈上分配还是堆上分配,如果是堆上分配则进入下一步。(开启逃逸分析需要设置jvm参...

  • JVM学习笔记与调优实战(三):Java对象内存分配与逃逸分析

    标签: JVM 1、Java对象的分配: 栈上分配线程私有小对象无逃逸支持标量替换无需调整(虚拟机自动优化,无需调...

  • 内存分配策略

    详解JVM对象分配内存 对象的内存分分配主要是指对上分配(也可栈上分配),对象主要分配在新生代Eden区,如果启动...

  • 《32个Java面试必考点》学习笔记之四------JVM

    JVM知识点汇总知识点详解JVM内存模型栈本地方法栈程序计数器堆方法区JMM与内存可见性类加载与卸载加载过程加载机...

  • Java中四种引用

    Java内存管理包括内存分配和内存回收。 内存分配:程序员通过new对象,JVM会自动为该对象分配内存。 内存回收...

  • Java编程语言:java中四种引用!欢迎补充

    Java内存管理包括内存分配和内存回收。 内存分配:程序员通过new对象,JVM会自动为该对象分配内存。 内存回收...

  • 2018-03-24

    Java学习随笔4 JVM的内存分配: 首先,jvm的内存主要分为三大块:堆,栈,方法区。 堆:jvm内存中最大的...

网友评论

      本文标题:JVM内存逃逸与栈上分配,程序员必须掌握的知识

      本文链接:https://www.haomeiwen.com/subject/wxyuxktx.html