堆内存分配的并发问题

柔情只为你懂 2022-09-02 05:19 206阅读 0赞

在实际的开发过程中,会经常的创建对象,作为虚拟机,必须保证线程安全。通常来讲虚拟机采用两种方式保证线程安全

一、CAS + 失败重试

CAS是一种乐观锁的实现方式,每次不加锁假设没有冲突的去完成某项操作,如果因为冲突导致操作失败就重试,直到成功为止。详见博客,传送地址:Java并发编程之 无锁(CAS)

二、TLAB

TLAB是在Java堆空间的伊甸园划分出来的针对每个线程的内存空间,专门在该区域为该线程创建的对象分配内存。

它的主要目的是在并发环境下进行内存分配的时候,减少线程之间对于内存空间的竞争,加速内存分配的速度。

TLAB本质上还是在Java堆中的,所以在TLAB区域的对象,也可以被其他线程访问。

如果没有使用TLAB,多个并发执行的线程创建对象,分配内存的时候,有可能在Java堆中的同一个位置申请,这就需要对这部分内存空间进行加锁或者采用CAS等操作保证线程安全,即保证该区域只分配给一个线程。

使用了TLAB之后,JVM会针对每个线程在堆内存中预留一个内存区域,在预留这个操作发生的时候,需要进行加锁或者采用CAS等操作进行保护,避免多个线程预留同一个区域。一旦确定了某个区域分配给某个线程,之后该线程需要分配内存的时候,会优先在这片区域申请。这个区域对于该线程分配内存这个操作而言是线程私有的,因此在分配的时候不用进行加锁等操作,从而既保护了线程安全又提升了分配速度。

注意: 当该线程创建的对象大于TLAB中的剩余内存或者TLAB的内存已用尽时,再采用CAS + 失败重试的方式分配内存。

发表评论

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

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

相关阅读

    相关 内存分配与栈区别

    1.内存分配方式 内存分配方式有三种:        1.从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,st