JVM常用概念之线程本地分配缓冲区(ThreadLocal Allocation Buffer,TLAB)

本文主要是介绍JVM常用概念之线程本地分配缓冲区(ThreadLocal Allocation Buffer,TLAB),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

当实例化一个Java类时,运行时环境必须为相关实例分配存储空间,在JRE中此存储空间分配操作是由内存管理器实现的(其实是JVM的垃圾回收器),由于内存管理器通常使用与运行时目标语言不同的语言编写(例如,Java 以 JVM 为目标,而 HotSpot JVM 是用 C++ 编写的),因此接口会变得更加模糊。而这种操作成本是相当高的,并且内存管理器也必须应对多线程场景下进行内存请求多压力。为了使Java程序的运行效率尽可能接近C++等语言的运行效率,针对JVM的内存管理器的执行效率需要进行优化。

1.优化方法

优化方法如允许线程分配整个内存块以满足其需求,并且只传输到 VM 以获取新块。在 Hotspot 中,这些块称为线程本地分配缓冲区 (TLAB),并且有一个复杂的机制来支持它们。请注意,TLAB 在时间意义上是线程本地的,这意味着它们像缓冲区一样接受当前分配。它们仍然是 Java 堆的一部分,线程仍然可以将对新分配对象的引用写入 TLAB 之外的字段等等。

所有已知的 OpenJDK GC 都支持 TLAB 分配。VM 代码的这一部分在它们之间基本是共享的。所有 Hotspot 编译器都支持 TLAB 分配,因此您通常会看到如下所示的对象分配生成代码:

0x00007f3e6bb617cc: mov    0x60(%r15),%rax        ; TLAB "current"
0x00007f3e6bb617d0: mov    %rax,%r10              ; tmp = current
0x00007f3e6bb617d3: add    $0x10,%r10             ; tmp += 16 (object size)
0x00007f3e6bb617d7: cmp    0x70(%r15),%r10        ; tmp > tlab_size?
0x00007f3e6bb617db: jae    0x00007f3e6bb61807     ; TLAB is done, jump and request another one
0x00007f3e6bb617dd: mov    %r10,0x60(%r15)        ; current = tmp (TLAB is fine, alloc!)
0x00007f3e6bb617e1: prefetchnta 0xc0(%r10)        ; ...
0x00007f3e6bb617e9: movq   $0x1,(%rax)            ; store header to (obj+0)
0x00007f3e6bb617f0: movl   $0xf80001dd,0x8(%rax)  ; store klass to (obj+8)
0x00007f3e6bb617f7: mov    %r12d,0xc(%rax)        ; zero out the rest of the object

2.指针碰撞分配

分配路径内联在生成的代码中,因此不需要调用 GC 来分配对象。如果我们请求分配耗尽了 TLAB 的对象,或者对象足够大而无法放入 TLAB,那么我们将采取“慢速路径”,要么在那里满足分配,要么返回新的 TLAB。请注意,最常见的“正常”路径只是将对象大小添加到 TLAB 当前光标,然后继续。

这就是为什么这种分配机制有时被称为“指针碰撞分配”。指针碰撞需要分配一块连续的内存,但这又带来了堆压缩的需要。请注意 CMS 如何在“老”代中进行空闲列表分配,从而实现并发清除,但它压缩了STW情况下堆中的“年轻代”集合,这受益于指针碰撞分配!年轻代集合中幸存下来的对象数量要少得多,这就是空闲列表分配的代价。

为了进行实验,我们可以使用 -XX:-UseTLAB 关闭 TLAB 功能。然后,所有分配都将进入本机方法,通常不建议这么做,如下所示:

-   17.12%     0.00%  org.openjdk.All  perf-31615.map- 0x7faaa3b2d125- 16.59% OptoRuntime::new_instance_C- 11.49% InstanceKlass::allocate_instance2.33% BlahBlahBlahCollectedHeap::mem_allocate  <---- entry point to GC0.35% AllocTracer::send_allocation_outside_tlab_event

3.总结

TLAB 是内存分配机制的主力:它们消除了分配器的并发瓶颈,提供了廉价的分配路径,并全面提高了性能。有趣的是,使用 TLAB 会导致更频繁的 GC ,只是因为内存分配非常便宜!相反,在任何内存管理器实现中没有快速分配路径肯定会隐藏内存回收性能问题,从而严重的影响JVM的性能。

这篇关于JVM常用概念之线程本地分配缓冲区(ThreadLocal Allocation Buffer,TLAB)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1048114

相关文章

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen

Spring Boot中JSON数值溢出问题从报错到优雅解决办法

《SpringBoot中JSON数值溢出问题从报错到优雅解决办法》:本文主要介绍SpringBoot中JSON数值溢出问题从报错到优雅的解决办法,通过修改字段类型为Long、添加全局异常处理和... 目录一、问题背景:为什么我的接口突然报错了?二、为什么会发生这个错误?1. Java 数据类型的“容量”限制

Java对象转换的实现方式汇总

《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映

SpringBoot请求参数接收控制指南分享

《SpringBoot请求参数接收控制指南分享》:本文主要介绍SpringBoot请求参数接收控制指南,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring Boot 请求参数接收控制指南1. 概述2. 有注解时参数接收方式对比3. 无注解时接收参数默认位置

Python的time模块一些常用功能(各种与时间相关的函数)

《Python的time模块一些常用功能(各种与时间相关的函数)》Python的time模块提供了各种与时间相关的函数,包括获取当前时间、处理时间间隔、执行时间测量等,:本文主要介绍Python的... 目录1. 获取当前时间2. 时间格式化3. 延时执行4. 时间戳运算5. 计算代码执行时间6. 转换为指

SpringBoot基于配置实现短信服务策略的动态切换

《SpringBoot基于配置实现短信服务策略的动态切换》这篇文章主要为大家详细介绍了SpringBoot在接入多个短信服务商(如阿里云、腾讯云、华为云)后,如何根据配置或环境切换使用不同的服务商,需... 目录目标功能示例配置(application.yml)配置类绑定短信发送策略接口示例:阿里云 & 腾

SpringBoot项目中报错The field screenShot exceeds its maximum permitted size of 1048576 bytes.的问题及解决

《SpringBoot项目中报错ThefieldscreenShotexceedsitsmaximumpermittedsizeof1048576bytes.的问题及解决》这篇文章... 目录项目场景问题描述原因分析解决方案总结项目场景javascript提示:项目相关背景:项目场景:基于Spring

Spring Boot 整合 SSE的高级实践(Server-Sent Events)

《SpringBoot整合SSE的高级实践(Server-SentEvents)》SSE(Server-SentEvents)是一种基于HTTP协议的单向通信机制,允许服务器向浏览器持续发送实... 目录1、简述2、Spring Boot 中的SSE实现2.1 添加依赖2.2 实现后端接口2.3 配置超时时

解决Maven项目idea找不到本地仓库jar包问题以及使用mvn install:install-file

《解决Maven项目idea找不到本地仓库jar包问题以及使用mvninstall:install-file》:本文主要介绍解决Maven项目idea找不到本地仓库jar包问题以及使用mvnin... 目录Maven项目idea找不到本地仓库jar包以及使用mvn install:install-file基

Spring Boot读取配置文件的五种方式小结

《SpringBoot读取配置文件的五种方式小结》SpringBoot提供了灵活多样的方式来读取配置文件,这篇文章为大家介绍了5种常见的读取方式,文中的示例代码简洁易懂,大家可以根据自己的需要进... 目录1. 配置文件位置与加载顺序2. 读取配置文件的方式汇总方式一:使用 @Value 注解读取配置方式二