逃逸分析——编译优化技术(最前沿的优化技术之一)

标签: 逃逸分析 JVM 对象分配 堆上?栈上?
47人阅读 评论(0) 收藏 举报
分类:

在Java中,典型的对象不再堆上分配的情况有两种:TLAB和栈上分配。

  • 一、为什么不在堆上分配
    我们知道堆是由所有线程共享的,既然如此那它就是竞争资源,对于竞争资源,必须采取必要的同步,所以当使用new关键字在堆上分配对象时,是需要锁的。既然有锁,就必定存在锁带来的开销,而且由于是对整个堆加锁,相对而言锁的粒度还是比较大的,当对象频繁分配时,不免影响效率。

所以对于某些特殊情况,可以采取避免在堆上分配对象的办法,以提高对象创建和销毁的效率。

  • 二、TLAB分配
    JVM在内存新生代Eden Space中开辟了一小块区域,由线程私有,称作TLAB(Thread-local allocation buffer),默认设定为占用Eden Space的1%。在Java程序中很多对象都是小对象且用过即丢,它们不存在线程共享也适合被快速GC,所以对于小对象通常JVM会优先分配在TLAB上,并且TLAB上的分配由于是线程私有所以没有锁开销。因此在实践中分配多个小对象的效率通常比分配一个大对象的效率要高。

  • 也就是说,Java中每个线程都会有自己的缓冲区称作TLAB(Thread-local allocation buffer),每个TLAB都只有一个线程可以操作,TLAB结合bump-the-pointer技术可以实现快速的对象分配,而不需要任何的锁进行同步,也就是说,在对象分配的时候不用锁住整个堆,而只需要在自己的缓冲区分配即可。

  • 三、栈上分配
    JVM在Server模式下的逃逸分析可以分析出某个对象是否永远只在某个方法、线程的范围内,并没有“逃逸”出这个范围,逃逸分析的一个结果就是对于某些未逃逸对象可以直接在栈上分配,由于该对象一定是局部的,所以栈上分配不会有问题。

  • 四、对象非堆上分配的思想和启发
    对象不在堆上分配主要的原因还是堆是共享的,在堆上分配有锁的开销。无论是TLAB还是栈都是线程私有的,私有即避免了竞争(当然也可能产生额外的问题例如可见性问题),这是典型的用空间换效率的做法。
    在实践中,类似的做法还有很多,例如Hadoop中对于Map过程在节点的本地内存中处理,直到最后Reduce过程再合并数据。对于任务之间可以分解到不同线程、进程的情况,就可以采用类似的做法用空间换效率,对吞吐率的提升有很大帮助。

JVM即时编译器(晚期)的优化技术:公共子表达式消除,数组范围检查消除,方法内联,逃逸分析参考运行期优化。这里主讲逃逸分析。

1.逃逸分析:

逃逸分析的基本行为是:分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法引用,作文参数传递到其他方法中,称为:方法逃逸。或者被线程访问,称为线程逃逸。 而如果一个对象不会逃逸到方法或者线程之外。就是别的方法无法通过任何途径访问到这个对象,这个对象或变量就可以进行一些高效优化。

逃逸分析,是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法

优化方法:

编译器可以使用逃逸分析的结果,对程序进行一下优化。

  1. 堆分配对象变成栈分配对象。一个方法当中的对象,对象的引用没有发生逃逸,那么这个方法可能会被分配在栈内存上而非常见的堆内存上。

  2. 消除同步。线程同步的代价是相当高的,同步的后果是降低并发性和性能。逃逸分析可以判断出某个对象是否始终只被一个线程访问,如果只被一个线程访问,那么对该对象的同步操作就可以转化成没有同步保护的操作,这样就能大大提高并发程度和性能。

  3. 矢量替代。逃逸分析方法如果发现对象的内存存储结构不需要连续进行的话,就可以将对象的部分甚至全部都保存在CPU寄存器内,这样能大大提高访问速度。

2.TLAB

JVM在内存新生代Eden Space中开辟了一小块线程私有的区域,称作TLAB(Thread-local allocation buffer)。默认设定为占用Eden Space的1%。在Java程序中很多对象都是小对象且用过即丢,它们不存在线程共享也适合被快速GC,所以对于小对象通常JVM会优先分配在TLAB上,并且TLAB上的分配由于是线程私有所以没有锁开销。因此在实践中分配多个小对象的效率通常比分配一个大对象的效率要高。
也就是说,Java中每个线程都会有自己的缓冲区称作TLAB(Thread-local allocation buffer),每个TLAB都只有一个线程可以操作,TLAB结合bump-the-pointer技术可以实现快速的对象分配,而不需要任何的锁进行同步,也就是说,在对象分配的时候不用锁住整个堆,而只需要在自己的缓冲区分配即可。

3. Java对象分配的过程

  1. 编译器通过逃逸分析,确定对象是在栈上分配还是在堆上分配。如果是在堆上分配,则进入选项2.

  2. 如果tlab_top + size <= tlab_end,则在在TLAB上直接分配对象并增加tlab_top 的值,如果现有的TLAB不足以存放当前对象则3.

  3. 重新申请一个TLAB,并再次尝试存放当前对象。如果放不下,则4.

  4. 在Eden区加锁(这个区是多线程共享的),如果eden_top + size <= eden_end则将对象存放在Eden区,增加eden_top 的值,如果Eden区不足以存放,则5.

  5. 执行一次Young GC(minor collection)。

  6. 经过Young GC之后,如果Eden区任然不足以存放当前对象,则直接分配到老年代。

原文链接

查看评论

JVM优化之逃逸分析(Escape Analysis)

在编程语言的编译优化原理中,分析指针动态范围的方法称之为逃逸分析。通俗一点讲,就是当一个对象的指针被多个方法或线程引用时,我们称这个指针发生了逃逸。 而用来分析这种逃逸现象的方法,就称之为逃逸分析。 ...
  • sz_bdqn
  • sz_bdqn
  • 2016-09-01 11:13:05
  • 560

JVM的逃逸技术介绍

程序小英雄 2016-12-26 15:42 在Java中每一个对象都有一定的作用域,理论上,一个对象在一块代码中构造,那么也应该在这块代码中被回收,但是实际上,我们经常会让一个对象存活更长...
  • u011277123
  • u011277123
  • 2016-12-28 14:29:40
  • 354

JIT编译器里面的“逃逸分析”(Escape analysis)

逃逸分析是一种编译器后端优化技术,它不是局部优化,而是过程间分析,这意味着它会分析函数调用关系,以判断变量是否“逃逸”出当前作用域范围。 对于JIT类语言来说,一般对象总是堆上分配,逃逸分析是否意味...
  • cteng
  • cteng
  • 2017-08-31 00:39:47
  • 172

Java_逃逸分析技术

什么是逃逸分析(Escape Analysis)? 在编程语言的编译优化原理中,分析指针动态范围的方法称之为逃逸分析。它跟静态代码分析技术中的指针分析和外形分析类似。 通俗一点讲,当一个对...
  • Kinger0
  • Kinger0
  • 2015-08-08 12:23:35
  • 3345

java虚拟机的逃逸分析

逃逸分析作为其他优化手段提供依据的分析技术,其基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他方法中,称为方法逃逸。甚至还有可能被外部线程...
  • xuqiaobo
  • xuqiaobo
  • 2016-09-14 09:14:40
  • 649

Java中的逃逸分析

大家一般认为new出来的对象都是被分配在堆上,但这并不是完全正确,通过对Java对象分配过程分析,我们发现对象除了可以被分配在堆上,还可以在栈或TLAB中分配空间。而栈上分配对象的技术基础是逃逸分析和...
  • xiaomingdetianxia
  • xiaomingdetianxia
  • 2017-09-01 14:40:56
  • 382

编译器优化技术

存在多种编译器优化技术来间接影响缓存的使用模式。下面仅举几例,且均假定编译器采用行主序(Row-major order)存储数组: 1. 循环交换(Loop Interchange) 考虑一个...
  • xinanzhung
  • xinanzhung
  • 2014-01-06 15:19:35
  • 993

深入分析JVM逃逸分析对性能的影响

逃逸分析(Escape Analysis)逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,称为方法逃逸。甚至还有可能被外部线程访问到,譬如赋值给类变量或可...
  • jijianshuai
  • jijianshuai
  • 2017-06-26 14:53:44
  • 1180

优化Go的模式

最近在优化Go项目,学习了一下Golang的调优相关内容。发现了一篇很不错的文章,翻译出来分享给大家。 之前写过一篇文章《为什么SignalFx metric proxy通过Go语言开发》,这篇...
  • u013870094
  • u013870094
  • 2017-07-09 15:05:44
  • 395
    个人资料
    持之以恒
    等级:
    访问量: 2302
    积分: 379
    排名: 22万+
    文章存档
    最新评论