G1垃圾回收器学习笔记-对象分配

二、对象分配

G1提供了两种对象的分配策略:基于线程本地分配缓冲区(TLAB,Thread Local Allocation Buffer)的快速分配和慢速分配。
无论是快速分配还是慢速分配,都应该在STW之外调用,都应该避免使用全局锁。因此优先进行无锁分配,再进行加锁,从而尽可能地满足并行化分配。

简单的实现是将释放的对象内存加入 FreeList,下次分配对象的时候,优先从 FreeList 中寻找合适的内存大小进行分配,之后再在主内存中撞针分配。

目前大多数应用内存分配是多线程的,都从主内存中分配,CAS 更新重试过于频繁导致效率低下。目前的应用,一般根据不同业务区分了不同的线程池,在这种情况下,一般每个线程分配内存的特性是比较稳定的。这里的比较稳定指的是,每次分配对象的大小,每轮 GC 分配区间内的分配对象的个数以及总大小。所以,我们可以考虑每个线程分配内存后,就将这块内存保留起来,用于下次分配,这样就不用每次从主内存中分配了。

在进行TLAB分配之前,会优先进行栈上分配,如果没有分配成功才会尝试进行TLAB

1.快速分配

TLAB的目的就是为了进行内存的快速分配。一般来说,从堆空间分配对象时,必须锁定整个堆,以便不会被其他线程中断和影响。因此TLAB试图通过为每一个线程分配一个缓冲区来避免和减少使用锁。

分配线程对象的时候,从JVM堆中分配一个固定大小的内存区域并将其作为线程的私有缓冲区,这个缓冲区就被称为TLAB

有了TLAB之后,只有为每个线程分配TLAB缓冲区的时候才需要锁定整个JVM堆。不同的线程不共享TLAB,我们尝试分配一个对象的时候优先从当前线程的TLAB中分配对象,不需要锁,所以达到了快速分配的目的

具体操作是,TLAB区是Eden区域中的一块内存,不同线程的TLAB都位于Eden区,所有的TLAB内存堆所有的线程都是可见的。每个线程都有一个TLAB的数据结构,但是仅仅只是保存待内存区间的起始地址(start)和结束地址(end)。在分配的时候也只在这个区间内做分配,从而达到无锁分配。top是当前的分配指针

G1中使用CAS来分配TLAB空间,一个TLAB空间分区中可能存在多个TLAB块,但是一个TLAB是不可能跨分区的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值