美文网首页Java
JVM内存逃逸

JVM内存逃逸

作者: ALTHE | 来源:发表于2016-06-07 19:14 被阅读820次

逃逸分析(Escape Analysis)是目前Java虚拟机中比较前沿的优化技术。

逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他地方中,称为方法逃逸。

例如:

StringBuffer sb是一个方法内部变量,上述代码中直接将sb返回,这样这个StringBuffer有可能被其他方法所改变,这样它的作用域就不只是在方法内部,虽然它是一个局部变量,称其逃逸到了方法外部。

甚至还有可能被外部线程访问到,譬如赋值给类变量或可以在其他线程中访问的实例变量,称为线程逃逸。

上述代码如果想要StringBuffer sb不逃出方法,可以这样写:

不直接返回StringBuffer,那么StringBuffer将不会逃逸出方法。

如果能证明一个对象不会逃逸到方法或线程外,则可能为这个变量进行一些高效的优化。

1. 栈上分配

我们都知道Java中的对象都是在堆上分配的,而垃圾回收机制会回收堆中不再使用的对象,但是筛选可回收对象,回收对象还有整理内存都需要消耗时间。如果能够通过逃逸分析确定某些对象不会逃出方法之外,那就可以让这个对象在栈上分配内存,这样该对象所占用的内存空间就可以随栈帧出栈而销毁,就减轻了垃圾回收的压力。

在一般应用中,如果不会逃逸的局部对象所占的比例很大,如果能使用栈上分配,那大量的对象就会随着方法的结束而自动销毁了。

2. 同步消除

线程同步本身比较耗时,如果确定一个变量不会逃逸出线程,无法被其它线程访问到,那这个变量的读写就不会存在竞争,对这个变量的同步措施可以清除。

3. 标量替换

Java虚拟机中的原始数据类型(int,long等数值类型以及reference类型等)都不能再进一步分解,它们就可以称为标量。相对的,如果一个数据可以继续分解,那它称为聚合量,Java中最典型的聚合量是对象。如果逃逸分析证明一个对象不会被外部访问,并且这个对象是可分解的,那程序真正执行的时候将可能不创建这个对象,而改为直接创建它的若干个被这个方法使用到的成员变量来代替。拆散后的变量便可以被单独分析与优化,可以各自分别在栈帧或寄存器上分配空间,原本的对象就无需整体分配空间了。

4. 总结

虽然概念上的JVM总是在Java堆上为对象分配空间,但并不是说完全依照概念的描述去实现;只要最后实现处理的“可见效果”与概念中描述的一直就没问题了。所以说,“you can cheat as long as you don't get caught”。Java对象在实际的JVM实现中可能在GC堆上分配空间,也可能在栈上分配空间,也可能完全就消失了。这种行为从Java源码中看不出来,也无法显式指定,只是聪明的JVM自动做的优化而已。

但是逃逸分析会有时间消耗,所以性能未必提升多少,并且由于逃逸分析比较耗时,目前的实现都是采用不那么准确但是时间压力相对较小的算法来完成逃逸分析,这就可能导致效果不稳定,要慎用。

由于HotSpot虚拟机目前的实现方法导致栈上分配实现起来比较复杂,因为在HotSpot中暂时还没有做这项优化。

Reference:Java的reference等于C的指针。所以,在Java的方法调用中,reference也要复制一份压入堆栈。在方法中对reference的操作就是对这个reference副本的操作。

相关JVM参数

-XX:+DoEscapeAnalysis 开启逃逸分析

-XX:+PrintEscapeAnalysis 开启逃逸分析后,可通过此参数查看分析结果。

-XX:+EliminateAllocations 开启标量替换

-XX:+EliminateLocks 开启同步消除

-XX:+PrintEliminateAllocations 开启标量替换后,查看标量替换情况。

相关文章

  • JVM内存逃逸

    逃逸分析(Escape Analysis)是目前Java虚拟机中比较前沿的优化技术。 逃逸分析的基本行为就是分析对...

  • Jvm优化技术

    Jvm优化技术有:逃逸分析、方法内联 一:Jvm优化技术之逃逸分析 1:概念 JVM的优化技术,可以有效减少Jav...

  • JVM内存模型(jvm 入门篇)

    概述 jvm 入门篇,想要学习jvm,必须先得了解JVM内存模型,JVM内存模型,JVM内存模型,JVM内存模型,...

  • GO内存逃逸是什么

    一、我们说内存逃逸时在说什么 问,内存逃逸是干什么的答,内存逃逸分析是编译器在编译优化时,用来决定变量应该分配在堆...

  • 内存逃逸

    在C中 val是栈上的局部变量,返回其指针是明显错误的。 而go的编译器则会进行逃逸分析,如下代码 使用 go t...

  • 回顾JVM内存分配

    回顾JVM内存分配回顾JVM内存分配

  • JVM

    简介 Jvm 系列一:Java类的加载机制Jvm系列二:JVM内存结构 --内存泄漏与内存溢出Jvm系列三:GC算...

  • 初见JVM内存区域

    初见JVM内存区域 JVM一个重要的机制就是自动内存管理机制,为了深入理解JVM的内存管理机制,了解JVM的内存...

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

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

  • 在金三银四的跳槽季中 你可能缺这一份JVM性能调优总结

    JVM调优配置 -server JVM运行的模式之一, server模式才能进行逃逸分析, JVM运行的模式还有m...

网友评论

    本文标题:JVM内存逃逸

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