JVM 深入浅出 - 【TLAB + 逃逸分析】

偏执的太偏执、 2023-10-02 17:00 129阅读 0赞

TLAB

TLAB(Thread Local Allocation Buffer)即线程本地分配缓存区,这是一个线程专用的内存分配区域。主要用来解决并发创建对象时分配空间造成指针碰撞的问题(减少CAS提升效率)与生命周期短小对象对GC带来的压力问题(朝生夕死,如下代码片段)。

  1. public void demoTest () {
  2. /*
  3. *demo对象的作用域在demoTest方法内部
  4. *demo对象在demoTest方法后执行创建,demoTest方法执行结束后就不在存在其他引用,开始等待GC回收
  5. */
  6. Demo demo = new Demo();
  7. demo.sayHello();
  8. }

不足之处:TLAB的空间浪费,空间不连续,过大(大于TLAB空间一点点)或者过小(小于TLAB空间很多)都会造成空间浪费;

目前线上环境建议开启TALB 【默认开启-XX: +UseTLAB显示开启, -XX:TLABWasteTargetPercent设置TLAB空间占Eden空间的百分比大小默认1%】。


逃逸分析

1)栈分配(JIT阶段)

经过逃逸分析确定一个方法中无法逃逸出此方法的对象可以直接在栈上分配。不在堆上分配对象,减轻GC负担

  1. public void demoTest () {
  2. Demo demo = new Demo();
  3. demo.sayHello();
  4. }

2)同步省略(消除同步,JIT阶段)

经过逃逸分析确定一个对象只能被一个线程私有访问,可以将对象同步操作转换为无同步保护的操作。通过锁消除提高并发的性能

  1. // 逃逸分析前
  2. public void test () {
  3. User user = new User();
  4. synchronized(user){
  5. user.sayHello();
  6. }
  7. }
  8. // 逃逸分析后 消除同步
  9. public void test () {
  10. User user = new User();
  11. user.sayHello();
  12. }

3)标量替换(JIT阶段)

经过逃逸分析确定一个对象不会被外界访问的话,就可以把这个对象拆解成若干个标量来代替。减少对象创建,节约堆内存空间,减轻GC负担

标量(Scalar)是指一个无法再分解成更小的数据的数据(Java中的原始数据类型就是标量)。聚合量(Aggregate)是指可以被分解的数据(java中的对象就是聚合量,因为他可以分解成其他聚合量和标量)。

  1. class User {
  2. public int a;
  3. public int b;
  4. public User(int a, int b){
  5. this.a = a;
  6. this.b = b;
  7. }
  8. }
  9. // 未逃逸分析
  10. public static void main (String[] args) {
  11. User user = new User(1,2);
  12. System.out.print("user.a is"+ user.a);
  13. System.out.print("user.b is"+ user.b);
  14. }
  15. // 逃逸分析 标量替换后
  16. public static void main (String[] args) {
  17. int a = 1;
  18. int b = 2;
  19. System.out.print("user.a is"+ a);
  20. System.out.print("user.b is"+ b);
  21. }

目前线上环境建议关闭逃逸分析 【关闭逃逸分析-XX:-DoEscapeAnalysis 1.6之后默认开启,关闭标量替换-XX:-EliminateAllocation】。


当开启逃逸分析与TLAB时java对象空间分配流程如下

watermark_type_ZHJvaWRzYW5zZmFsbGJhY2s_shadow_50_text_Q1NETiBAT2NlYW5A5LiK5rqQ56CB_size_19_color_FFFFFF_t_70_g_se_x_16

发表评论

表情:
评论列表 (有 0 条评论,129人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JVM逃逸分析

      我们都知道Java中的对象默认都是分配到堆上,在调用栈中,只保存了对象的指针。当对象不再使用后,需要依靠GC来遍历引用树并回收内存。如果堆中对象数量太多,回收对象还有整理内

    相关 Java之JVM逃逸分析

    引言: 逃逸分析(Escape Analysis)是众多JVM技术中的一个使用不多的技术点,本文将通过一个实例来分析其使用场景。 概念 逃逸分析,是一种可以有效减少Ja

    相关 JVM逃逸分析

    摘要: 本文基于周志明著作的《深入了解Java虚拟机》主要介绍了逃逸分析的定义,以及逃逸分析的一些应用,方便复习 `逃逸分析`(Escape Analysis)是目前Jav

    相关 逃逸分析、栈上分配、TLAB

    引言        我们知道,一般在java程序中,new的对象是分配在堆空间中的,但是实际的情况是,大部分的new对象会进入堆空间中,而并非是全部的对象,还有另外两个地