• JVM 一张图带你了解内存分配过程 搞懂逃逸分析|标量替换|指针碰撞|空闲列表|TLAB


    面试题

    在栈上分配对象,使用标量替换的目的是什么?

    内存分配过程

    逃逸分析

    如何确定对象是否在栈上进行分配,当然得通过逃逸分析了。
    逃逸分析是什么意思呢?我们直接看两段代码
    代码1:

    public Student get(){
        Student student = new Student();
        student.setName("乐哥聊编程");
        student.setStuNo("乐哥聊编程");
        student.setAge(23);
        return student;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码2:

    public void save(){
        Student student = new Student();
        student.setName("乐哥聊编程");
        student.setStuNo("乐哥聊编程");
        student.setAge(23);
        // 保存到数据
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    比对两段代码,如果jvm开启逃逸分析:
    那么代码1在经过逃逸分析之后:student不允许对象在栈上分配
    那么代码2在经过逃逸分析之后:student允许对象在栈上分配

    为什么会这样呢?
    因为虚拟机在分析代码1后,发现student对象生成之后,被返回了,使用范围不止在当前方法,所以如果在栈上分配的话,那么当前方法结束后,对象就会被移除,但是此时对象是返回给当前方法的调用者的,导致拿到的是空的,最终导致程序出现问题。

    同样道理,在分析代码2之后,student只在当前方法使用,所以允许在栈上分配

    标量替换

    当通过逃逸分析之后,如果对象在栈上分配,jvm将会通过标量替换拆解对象。
    标量替换 = 将对象拆解成不能再分为止
    聚合量 =对象中可以再次被分解的属性

    public class Student {
        private String name;
        private String stuNo;
        private Teacher teacher;
        private int age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Student对象首先拆解成name,stuNo,age
    然后继续拆解Teacher对象,同样拆解方式。

    内存划分方式

    指针碰撞

    将内存对半拆分,中间放一个指针,指针左边是已分配内存空间,右边是空闲内存空间。申请内存地址时,指针向右移动

    空闲列表

    空闲列表记录了哪段内存地址是空闲的,申请内存空间时,从这个空闲列表中的区域获取内存地址。

    如果解决内存分配并发问题?

    • CAS

    compareAndSwap(a,oldValue,newValue)

    • TLAB (本地线程分配缓冲区)

    每个线程预先在堆中预先分配一小块内存

  • 相关阅读:
    QT 简易计算器
    技术质检员:接口的幂等性如何设计?
    【lambda表达式】变量作用域和lambda 表达式的处理
    每日一练--IT冷知识&C/C++--第一天
    JAVA编程规范(阿里巴巴)
    Python Opencv实践 - 车辆统计(2)检测线绘制,车辆数量计数和显示
    记一次ThreadLocal引发的线上故障
    高等教育学备考一
    BigLEN(rat)脑内最丰富的多肽之一、LENSSPQAPARRLLPP
    使用Lightrun对Java应用程序进行性能调整
  • 原文地址:https://blog.csdn.net/weixin_34311210/article/details/127948381