TLAB(Thread Local Allocation Buffer)
TLAB是虚拟机在堆内存的eden划分出来的一块专用空间,是线程专属的。在虚拟机的TLAB功能启动的情况下,在线程初始化时,虚拟机会为每个线程分配一块TLAB空间,只给当前线程使用,这样每个线程都单独拥有一个空间,如果需要分配内存,就在自己的空间上分配,这样就不存在竞争的情况,可以大大提升分配效率。这里值得注意的是,我们说TLAB是线程独享的,但是只是在“分配”这个动作上是线程独享的,至于在读取、垃圾回收等动作上都是线程共享的。而且在使用上也没有什么区别。
也就是说,虽然每个线程在初始化时都会去堆内存中申请一块TLAB,并不是说这个TLAB区域的内存其他线程就完全无法访问了,其他线程的读取还是可以的,只不过无法在这个区域中分配内存而已。
并且,在TLAB分配之后,并不影响对象的移动和回收,也就是说,虽然对象刚开始可能通过TLAB分配内存,存放在Eden区,但是还是会被垃圾回收或者被移到Survivor Space、Old Gen等。
还有一点需要注意的是,我们说TLAB是在eden区分配的,因为eden区域本身就不太大,而且TLAB空间的内存也非常小,默认情况下仅占有整个Eden空间的1%。所以,必然存在一些大对象是无法在TLAB直接分配。
遇到TLAB中无法分配的大对象,对象还是可能在eden区或者老年代等进行分配的,但是这种分配就需要进行同步控制,这也是为什么我们经常说:小的对象比大的对象分配起来更加高效。
TLAB带来的问题
虽然在一定程度上,TLAB大大的提升了对象的分配速度,但是TLAB并不是就没有任何问题的。
前面我们说过,因为TLAB内存区域并不是很大,所以,有可能会经常出现不够的情况。在《实战Java虚拟机》中有这样一个例子:
比如一个线程的TLAB空间有100KB,其中已经使用了80KB,当需要再分配一个30KB的对象时,就无法直接在TLAB中分配,遇到这种情况时,有两种处理方案:
1、如果一个对象需要的空间大小超过TLAB中剩余的空间大小,则直接在堆内存中对该对象进行内存分配。
2、如果一个对象需要的空间大小超过TLAB中剩余的空间大小,则废弃当前TLAB,重新申请TLAB空间再次进行内存分配。
以上两个方案各有利弊,如果采用方案1,那么就可能存在着一种极端情况,就是TLAB只剩下1KB,就会导致后续需要分配的大多数对象都需要在堆内存直接分配。
如果采用方案2,也有可能存在频繁废弃TLAB,频繁申请TLAB的情况,而我们知道,虽然在TLAB上分配内存是线程独享的,但是TLAB内存自己从堆中划分出来的过程确实可能存在冲突的,所以,TLAB的分配过程其实也是需要并发控制的。而频繁的TLAB分配就失去了使用TLAB的意义。
为了解决这两个方案存在的问题,虚拟机定义了一个refill_waste的值,这个值可以翻译为“最大浪费空间”。
当请求分配的内存大于refill_waste的时候,会选择在堆内存中分配。若小于refill_waste值,则会废弃当前TLAB,重新创建TLAB进行对象内存分配。
前面的例子中,TLAB总空间100KB,使用了80KB,剩余20KB,如果设置的refill_waste的值为25KB,那么如果新对象的内存大于25KB,则直接堆内存分配,如果小于25KB,则会废弃掉之前的那个TLAB,重新分配一个TLAB空间,给新对象分配内存。
TLAB使用的相关参数
TLAB功能是可以选择开启或者关闭的,可以通过设置-XX:+/-UseTLAB参数来指定是否开启TLAB分配。
TLAB默认是eden区的1%,可以通过选项-XX:TLABWasteTargetPercent设置TLAB空间所占用Eden空间的百分比大小。
默认情况下,TLAB的空间会在运行时不断调整,使系统达到最佳的运行状态。如果需要禁用自动调整TLAB的大小,可以使用-XX:-ResizeTLAB来禁用,并且使用-XX:TLABSize来手工指定TLAB的大小。
TLAB的refill_waste也是可以调整的,默认值为64,即表示使用约为1/64空间大小作为refill_waste,使用参数:-XX:TLABRefillWasteFraction来调整。
如果想要观察TLAB的使用情况,可以使用参数-XX+PringTLAB 进行跟踪。
总结
为了保证对象的内存分配过程中的线程安全性,HotSpot虚拟机提供了一种叫做TLAB(Thread Local Allocation Buffer)的技术。
在线程初始化时,虚拟机会为每个线程分配一块TLAB空间,只给当前线程使用,当需要分配内存时,就在自己的空间上分配,这样就不存在竞争的情况,可以大大提升分配效率。
所以,“堆是线程共享的内存区域”这句话并不完全正确,因为TLAB是堆内存的一部分,它在读取上确实是线程共享的,但是在内存分配上,是线程独享的。
TLAB的空间其实并不大,所以大对象还是可能需要在堆内存中直接分配。那么,对象的内存分配步骤就是先尝试TLAB分配,空间不足之后,再判断是否应该直接进入老年代,然后再确定是再eden分配还是在老年代分配。
TLAB(Thread Local Allocation Buffer)相关推荐
- JVM线程本地分配缓冲区(Thread Local Allocation Buffer)TLAB详解
最近在看java性能相关方面的书籍.然后在GC调优相关的部分出现了,线程本地分配缓冲区的名词,对于它的调优级为重要,所以就梳理一下这个到底是什么?为什么他对于JVM性能如此重要. 什么是JVM线程本地 ...
- 在TLAB(线程本地分配缓存)上分配对象
目录 使用TLAB性能差异 示例 分配策略 Java对象分配过程 JVM的Thread Local Allocation Buffer,即TLAB线程本地分配缓存,作用是加速分配对象空间,以前的日志里 ...
- 【智能算法】迭代局部搜索(Iterated Local Search, ILS)详解
更多精彩尽在微信公众号[程序猿声] 迭代局部搜索(Iterated Local Search, ILS) 00 目录 局部搜索算法 简单局部搜索 迭代局部搜索 01 局部搜索算法 1.1 什么是局部搜 ...
- WLAN(Wireless Local Area Network)——无线局域网
目录 一.WLAN基础 1.分类 2.各种无线网络技术应用 3.WLAN的定义 4.WLAN技术标准 (1)802.11 (2)802.11b (3)802.11a (4)802.11g (5)802 ...
- 随想录(thread类的编写)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 曾经有一段时间我不是很清楚在c++下面,为什么创建一个thread只需要继承一下.然后重写一下r ...
- Java内存区域(运行时数据区域)和内存模型(JMM)
原文作者:czwbig 原文:https://www.cnblogs.com/czwbig/p/11127124.html Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数 ...
- 读书笔记——深入理解JVM(JVM自动内存管理)
简介 本系列为<深入理解Java虚拟机-JVM高级特性与最佳实践>一书的阅读笔记. 本书开头介绍了JVM发展的历史,接着介绍了JVM是如何实现自动内存管理的. 本章节主要介绍: JVM的存 ...
- 精华推荐 | 【JVM深层系列】「GC底层调优系列」一文带你彻底加强夯实底层原理之GC垃圾回收技术的分析指南(GC原理透析)
前提介绍 很多小伙伴,都跟我反馈,说自己总是对JVM这一块的学习和认识不够扎实也不够成熟,因为JVM的一些特性以及运作机制总是混淆以及不确定,导致面试和工作实战中出现了很多的纰漏和短板,解决广大小伙伴 ...
- WCF后续之旅(11): 关于并发、回调的线程关联性(Thread Affinity)
对于一般的多线程操作,比如异步地进行基于文件系统的IO操作:异步地调用Web Service:或者是异步地进行数据库访问等等,是和具体的线程无关的.也就是说,对于这些操作,任意创建一个新的线程来执行都 ...
最新文章
- ***网站必备:(经典语句)
- Windows批量添加防火墙例外端口
- 2018危机与机遇丨PMCAFF年度精选合集
- RESTful Web服务可发现性,第4部分
- python如何输出两列数据_如何用python将一列数据分为两列?
- java-成员变量的属性与成员函数的覆盖
- matlab 传递函数 画出频率响应,MATLAB环境下频率响应曲线的绘制方法
- MATLAB_R2018b安装教程
- 触动精灵 获取getColor颜色失败
- java 一元二次方程_java求解一元二次方程
- java合成wav在linux出错,Java audio fails to play wav file in Linux
- 易大师接口自动化测试平台如何创建不同协议的接口并进行测试
- 数据库MySQL(基础六)
- openwrt mesh网络设置
- 第十二届蓝桥杯 2021年省赛真题 (Java 大学A组) 第一场
- 将id=5以及emp_no=10001的行数据替换成id=5以及emp_no=10005
- new FileReader()
- Python - 文本处理模块
- Windows server 2019 - 磁盘加密(BitLocker)
- PIPI OJ 1334: PIPI计数(unordered_map的应用)