最近在看java性能相关方面的书籍。然后在GC调优相关的部分出现了,线程本地分配缓冲区的名词,对于它的调优级为重要,所以就梳理一下这个到底是什么?为什么他对于JVM性能如此重要。

什么是JVM线程本地分配缓冲区(Thread Local Allocation Buffer)TLAB?

JVM在分配新对象时,将在专用于原始线程的TLAB(线程本地分配缓冲区)中分配该对象。由于每个线程只能写入自己的TLAB,因此不需要同步。TLAB默认情况下处于启用状态,可以随时使用-XX:-UseTLAB调整标志将其禁用(除非你想找刺激)。

TLAB对象在一个共享的空间中分配,我们需要采用些同步机制来管理空间内的空闲空间指针。每个线程有固定的分配区域,分配对象时,线程之间不需要进行任何的同步。(这是利用线程本地变量避免锁争用的)。

TLAB是如何分配的?

通常,TLAB的使用对程序员和终端用户而言是完全透明的:默认情况下TLAB就是开启的,JVM管理着它们的大小及如何使用。我们需要意识到的最重要的事是TLAB都不大,因此大型对象无法在TLAB内进行分配。大型对象必须直接从堆上分配,由于需要同步,一旦TLAB空间用尽,特定大小的对象就无法再继续分配。这时,JVM可以有不同的选择。

  • 一个选项是回收这块TLAB,为该线程分配一块新的TLAB。由于TLAB只是Eden空间中的一个区段,下一次新生代垃圾收集时这块TLAB整个都会被回收,并在之后的空间分配中重用。
  • JVM还可以直接在堆上分配对象,保留当前的TLAB不动(至少在线程分配新的对象到TLAB之前保持不变)。假设发生下面这种情况,TLAB的大小为100KB,其中75 KB都已经被占用。这时来了个新的空间分配请求,需要分配30 KB的空间,我们可以回收整个TLAB,这种方式会浪费25 KB的Eden空间。或者直接在堆上分配这个对象,如果下一次的对象分配空间要求小于等于 25KB,线程还可以将 TLAB的空闲空间分配给对象。

JVM提供了各种参数可以控制这些行为,但这一切都取决于TLAB大小。默认情况下,TLAB的大小由三个因素决定:应用程序的线程数。Eden空间的大小和以及线程分配率。由于TLAB的大小计算一定程度上取决于线程分配率。不大可能精准的预测TLAB的大小。

因此两类的应用程序会受益于TLAB参数的调整:需要分配大量巨型对象的应用程序,以及相对于Eden空间的大小而言,应用程序线程数量过多的应用。默认情况下,TLAB就是开启的;使用-Xx: -UseTLAB可以关闭TLAB,不过考虑到TLAB带来的性能提升,关闭这个功能不是个明智的决定。

如何调整TLAB大小?

可以通过-XX:TLABsize=N 来显示的调整TLAB大小(默认是0)。这个标志只能设置TLAB的初始大小,为了避免在每次GC时都调整TLAB的大小,可以使用-XX:-ResizeTLAB标志(大多数的平台上,这个参数的默认值都是true)。这是通过调整TLAB,充分提升对象分配性能最简单的方法(坦率地说,通常这也是最有效的方法)。

一个新的对象无法适配到当前的TLAB中(但是可以容纳于一一个新的、空闲的TLAB中)时,JVM就需要做一些抉择:到底是在堆上分配这个对象,还是要回收当前的TLAB,重新分配-一个新的TLAB来完成这次对象分配,这个决策取决于几个参数。TLAB日志的输出中,refill waste 的值代表了决策的当前阈值:如果TLAB无法容纳新对象的大小超过这个阈值,那么就会在堆上分配新的对象。如果有问题的对象的大小比这个阈值小,就回收老的TLAB空间。

这个值是动态计算得出的,但是默认的初始值是TLAB大小的1%,或者是由参数-XX:TLABWasteTargetPercent=N特别设定的值。每当发生堆上的分配,这个值就增大一笔,增量值由参数-XX:TLABWasteIncrement=N设定(默认值为4)。 这种设计能够避免线程达到TLAB空间占用的阈值,从而持续地在堆上分配对象:随着目标百分比(TargetPercentage)的增大,TLAB空间被回收的几率也在增加。调整TLABWasteTargetPercent参数的结果往往同时伴随着TLAB空间大小的调整,所以,虽然可以调整这个参数,但是效果往往不那么确定。

最终,TLAB空间调整生效时,其容量的最小值可以使用-XX:MinTLABSize=N 参数设置(默认为2 KB)。TLAB空间的最大容量略小于1 GB (使用整型数组可以用到TLAB空间的最大上限,由于对象对齐的原因,最大上限会向下圆整),并且不能修改。

JVM线程本地分配缓冲区(Thread Local Allocation Buffer)TLAB详解相关推荐

  1. 本地线程分配缓冲_线程本地分配缓冲区

    本地线程分配缓冲 最近,我一直在研究遭受严重性能问题的Java应用程序. 在许多问题中,真正引起我注意的一个问题是新对象的分配速度相对较慢(应用程序分配了大量的相当大的对象). 后来发现,原因是大量的 ...

  2. TLAB(Thread Local Allocation Buffer)

    TLAB是虚拟机在堆内存的eden划分出来的一块专用空间,是线程专属的.在虚拟机的TLAB功能启动的情况下,在线程初始化时,虚拟机会为每个线程分配一块TLAB空间,只给当前线程使用,这样每个线程都单独 ...

  3. 线程本地分配缓存TLAB

    概念 为了避免一系列的非线程安全问题,同时还能提升内存分配的吞吐量,它是在eden空间进行分配的,每个线程都有一个缓冲区域,空间只有Eden的1%,可以通过-XX:UseTLAB来配置是否开启tlab ...

  4. 在TLAB(线程本地分配缓存)上分配对象

    目录 使用TLAB性能差异 示例 分配策略 Java对象分配过程 JVM的Thread Local Allocation Buffer,即TLAB线程本地分配缓存,作用是加速分配对象空间,以前的日志里 ...

  5. 如何将一个完整项目推到码云_怎么将本地项目放到码云(gitee)上面?图文详解

    原标题:怎么将本地项目放到码云(gitee)上面?图文详解 git的好处什么的,在此就不多赘述.现在很多公司都在用git了. 那么怎么将本地已经有的项目放到码云(gitee)上呢? 前置条件说明: 1 ...

  6. 天津理工大学《操作系统》实验二,存储器的分配与回收算法实现,代码详解,保姆式注释讲解

    天津理工大学<操作系统>实验二,存储器的分配与回收算法实现,代码详解,保姆式注释讲解 实验内容 1. 本实验是模拟操作系统的主存分配,运用可变分区的存储管理算法设计主存分配和回收程序,并不 ...

  7. 8.JVM 关于对象分配在堆、栈、TLAB的理解

    引言 我们知道,一般在java程序中,new的对象是分配在堆空间中的,但是实际的情况是,大部分的new对象会进入堆空间中,而并非是全部的对象,还有另外两个地方可以存储new的对象,我们称之为栈上分配以 ...

  8. C++ std::thread 和 std::jthread 使用详解 (含C++20新特性)

    目录 std::thread std::thread 构造函数 观察器 操作 std::jthread std::jthread 构造函数 观察器 操作 停止记号处理 管理当前线程的函数 yield( ...

  9. JVM性能调优篇07-阿里巴巴Arthas工具详解

    Arthas工具 Arthas 是 Alibaba 在 2018 年 9 月开源的 Java 诊断工具.支持 JDK6+, 采用命令行交互模式,可以方便的定位和诊断线上程序运行问题.Arthas 官方 ...

最新文章

  1. TCP:传输控制协议简单讲解(八)
  2. 利用grep命令查找文件内容
  3. struts2下拉框在不同情况下的各种用法
  4. Python基础学习四 函数
  5. sphinx随笔记了一下
  6. [CF1442 D] Sum(分治优化dp + 结论)
  7. php dos,防止用户利用PHP代码DOS造成用光网络带宽
  8. Flowable 数据库表结构 ACT_HI_VARINST
  9. 华为路由器A1如何设置虚拟服务器,华为路由器A1如何设置虚拟服务器
  10. 中日文字编码转换_关于编码你必须知道的知识和技巧
  11. Wi-Fi 还是蜂窝?搞物联网怎么选择连接协议?
  12. 使用postman调试web API
  13. 一位软件工程师的7年总结
  14. MySQL的下载安装教程
  15. 使用Chrome谷歌浏览器打开Axure原型图
  16. 29.正向和负向Lookahead
  17. 一步步用python制作游戏外挂 - blueel - 博客园
  18. CIO40: IT 人之读书与家庭
  19. windows 通过cmd命令连接wifi
  20. XP系统加入域提示无法找到网络路径处理方法

热门文章

  1. 机房服务器维修,机房维护方案
  2. 什么是 PKI? 公钥基础设施的定义和指南
  3. 4.1 使用常见的各种字体属性 [原创Excel教程]
  4. 计算机打印unknow,系统安装打印机驱动提示unknown device解决方法
  5. 端午假期你是如何过的?
  6. WDM在不同Windows版本上的音频支持
  7. pacemaker+corosync的一些总结
  8. c语言减少控制流变量,C语言 第3章 控制流 (1简单程序设计).ppt
  9. 怎样进行两台电脑之间的数据传输?
  10. 【C语言】scanf函数格式控制符