JVM内存模型-4

75 阅读2分钟

「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。

对象分配并发安全问题

Java程序天生是多线程的,如果一个创建对象的程序处于多线程并发执行,那么就会产生线程安全问题,试想:如果A线程准备将对象分配在堆内存的x_0001处,此时B线程也执行到创建对象,在申请空间的时候发现x_0001处未分配…后续的问题就不用说了。那么JVM是怎么解决这个问题的呢?

1.CAS无锁机制

这种方式最易想到,采用锁机制进行线程并发问题可以很好地解决。 在这里插入图片描述 但是毕竟全局使用CAS锁机制,如果在高并发情况而且创建对象的时间比较长,那么这种方式性能的问题就凸显了出来,于是第二种方式孕育而生。

2.TLAB(本地线程分配缓冲Thread Local Allocation Buffer)

TLAB顾名思义,JVM将每个线程在堆中预先分配一块私有内存空间 ,这用每个独立的线程都有属于自己的Buffer,如果有对象需要分配那么就会在自己的Buffer中创建对象,当Buffer用满了以后就会重新分配缓冲区,此时这个阶段是需要CAS锁机制保证安全。JVM可以通过制定启动参数-XX:+/-UseTLAB来指定。

内存空间初始化

对象分配内存完成之后,JVM需要将对象的实例数据赋予默认值,比如对象类型赋值null,基本类型赋值默认值,例如int -> 0,boolean -> false。

设置

JVM还需要堆对象进行必要的设置,例如这个对象属于哪个类的实例、GC分代年龄等,这些信息存储在对象头中。需要注意的是对象的哈希码并不是在此刻计算(实际上的哈希码会延后到真正调用Object::hashCode()方法时才计算赋值)

初始化

执行构造方法,实例变量赋真实值。