对象一定分配在堆中吗?聊聊TLAB和逃逸分析技术

打印 上一主题 下一主题

主题 889|帖子 889|积分 2671

TLAB

TLAB是虚拟机在堆内存的eden分别出来的一块专用空间,是线程专属的。在虚拟机的TLAB功能启动的情况下,在线程初始化时,虚拟时机为每个线程分配一块TLAB空间(包含在 Eden 空间内),只给当前线程使用,这样每个线程都单独拥有一个空间,如果需要分配内存,就在自己的空间上分配,这样就不存在竞争的情况,可以大大提升分配服从。
多线程同时分配内存时,使用 TLAB 可以避免一系列的非线程安全问题,同时还能提升内存分配的吞吐量,因此我们可以将这种内存分配方式称为快速分配策略
为什么要有 TLAB :

  • 堆区是线程共享的,任何线程都可以访问到堆区中的共享数据
  • 由于对象实例的创建在 JVM 中非常频繁,因此在并发环境下从堆区中分别内存空间是线程不安全的
  • 为避免多个线程操作同一地址,需要使用加锁等机制,进而影响分配速度
固然了,不是全部的对象实例都可以或许在 TLAB 中成功分配内存,但 JVM 确实是将 TLAB 作为内存分配的首选。
在步调中,可以通过 -XX:UseTLAB 设置是否开启 TLAB 空间。
默认情况下,TLAB 空间的内存非常小,仅占有整个 Eden 空间的 1%,可以通过 -XX:TLABWasteTargetPercent 设置 TLAB 空间所占用 Eden 空间的百分比大小。
一旦对象在 TLAB 空间分配内存失败时,JVM 就会尝试着通过使用加锁机制确保数据操作的原子性,从而直接在 Eden 空间中分配内存
逃逸分析技术

对象一定分配在堆中吗?

不一定的,JVM通过「逃逸分析」,那些逃不出方法的对象就会在栈上分配。
栈上分配的条件


  • 作用域不会逃逸出方法的对象
  • 小对象(一般几十个byte);大对象无法在栈上分配
  • 标量更换:若逃逸分析证明一个对象不会逃逸出方法,不会被外部访问,并且这个对象是可以被分解的,那步调在真正执行的时候可能不创建这个对象,而是直接创建这个对象分解后的标量来代替。这样就无需在对对象分配空间了,只在栈上为分解出的变量分配内存即可。
什么是逃逸分析

逃逸分析(Escape Analysis),是一种可以有效淘汰Java 步调中同步负载和内存堆分配压力的跨函数全局数据流分析算法。
通过逃逸分析,Java Hotspot编译器可以或许分析出一个新的对象的引用的使用范围,从而决定是否要将这个对象分配到堆上。

  • 一个对象在方法中被定义后,对象如果只在方法内部使用,则认为没有发生逃逸;(没有发生逃逸的对象,会在栈上分配)
  • 当一个对象在方法中被定义后,它被外部方法所引用,则认为发生了逃逸。
怎样快速的判断是否发生了逃逸分析?

  • 看new的对象实体是否有可能在方法外被调用。注意是看new 出来的实体,而不是谁人引用变量。
普通点讲,如果一个对象的指针被多个方法大概线程引用时,那么我们就称这个对象的指针发生了逃逸。

逃逸分析的利益


  • 栈上分配,可以降低垃圾收集器运行的频率。
  • 同步消除,如果发现某个对象只能从一个线程可访问,那么在这个对象上的操作不需要同步。
  • 标量更换,把对象分解成一个个基本类型,并且内存分配不再是分配在堆上,而是分配在栈上。这样的利益有

    • 淘汰内存使用,因为不用生成对象头。
    • 步调内存回收服从高,并且GC频率也会淘汰。

小结

关于逃逸分析的论文在1999年就已经发表了,但直到JDK 1.6才有实现,而且这项技术到如今也并不是非常成熟的。
其根本原因就是无法保证逃逸分析的性能消耗一定能高于他的消耗。虽然经过逃逸分析可以做标量更换、栈上分配、和锁消除。但是逃逸分析自身也是需要进行一系列复杂的分析的,这其实也是一个相对耗时的过程。
一个极端的例子,就是经过逃逸分析之后,发现没有一个对象是不逃逸的。那这个逃逸分析的过程就白白浪费掉了。
口试题专栏

Java口试题专栏已上线,接待访问。

  • 如果你不知道简历怎么写,简历项目不知道怎么包装;
  • 如果简历中有些内容你不知道该不应写上去;
  • 如果有些综合性问题你不知道怎么答;
那么可以私信我,我会尽我所能资助你。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

刘俊凯

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表