Java逃逸分析是什么?

南风 2020年10月22日 312次浏览

JVM内存结构

一、为啥对象和数组不一定在JVM堆上分配内存?

前一节中我们知道本地方法栈、程序计数器和栈区是线程内私有“财产“,外部无法共用,而堆区和方法区是线程公用“财产”,每个线程都有一份,以前我们通常认知对象和数据基本上内存基本上都分配在堆区,使用结束需要JVM老大哥进行回收,但是为啥不是所有的对象和数组都分配在堆区呢?因为有以下逃逸分析会影响其内存分配的位置:
Java Code run

二、逃逸分析是什么?

 Java class在解释期间,JIT会对代码做很多优化。其中有一部分优化的目的就是减少内存堆分配压力,其中一种重要的技术叫做逃逸分析。JVM正常情况下是一行一行对字节码进行解释,转化成机器码,
 引入了 JIT 技术后,Java程序还是通过解释器进行解释执行,当JVM发现某个方法或代码块运行特别频繁的时候,就会认为这是“热点代码”(Hot Spot Code)。然后JIT会把部分“热点代码”翻译成本地机器相关的机器码,并进行优化,然后再把翻译后的机器码缓存起来,以备下次使用。
 使用了逃逸分析之后,解释器可以对代码做以下几点优化:

  • 1、同步省略。如果一个对象被发现只能从一个线程被访问到,那么对于这个对象的操作可以不考虑同步。
  • 2、将堆分配转化为栈分配。如果一个对象在子程序中被分配,要使指向该对象的指针永远不会逃逸,对象可能是栈分配的候选,而不是堆分配。
  • 3、分离对象或标量替换。有的对象可能不需要作为一个连续的内存结构存在也可以被访问到,那么对象的部分(或全部)可以不存储在内存,而是存储在CPU寄存器中。

在解释器执行期间,如果发现对象没有逃逸出方法,有可能堆内存分配会被优化成栈内存分配,但是不是所有的对象都会被优化,当对象被分配到栈上时,不需要通过JVM进行GC,对象会在方法结束后被回收。

三、为什么同样是方法局部对象,只有一部分对象成功逃逸到栈上分配呢?【待深入研究】