news 2026/4/23 15:06:49

JVM的栈上分配、TLAB、PLAB有啥区别?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JVM的栈上分配、TLAB、PLAB有啥区别?

我们在学习 G1 回收器的时候,一般我们都会接触到 TLAB 和 PLAB 这两个术语。它们都是为了提高内存分配效率而存在的,但它们和栈上分配有什么区别呢?今天,就让树哥带着大家盘一盘。

栈上分配

稍微了解过 Java 虚拟机内存结构的同学都知道,在 Java 虚拟机中有两个关键的存储数据节点,那就是:堆与栈。

其中堆是所有线程共享的一块内存,几乎所有对象的分配都在这块内存中。而栈则是线程自己私有的,只存储线程自己的局部变量等信息。每个线程都有自己的栈,栈信息无法在线程之间共享。

一般情况下,每个线程如果有新建的对象,那么会跟 JVM 申请在堆上创建对应的对象,而线程的栈则存储了指向堆对象的指针。每当一个线程想创建一个对象时,首先会请求 JVM,之后 JVM 进行协调,创建完成之后再告诉线程,线程最后将引用放到栈中。

在对象创建的这个过程,堆和栈之间的关系就像是列车的中央调度室和火车的关系。每次线程需要分配内存空间,都需要去到堆去申请空间,会耗费不少时间和精力。

这个时候有人就发现,线程的有些对象其实别人也不会访问到,放在堆中貌似也没什么大作用。于是他提出:对于这些其他线程不会访问的对象,我们能不能让线程自己分配在它自己的栈空间上?这样不就可以节省不少交互时间了么!

这个方法确实不错,如果能实现应该可以提高对象创建的时间,提高虚拟机的运行效率。

但问题是:我怎么知道哪些对象可以分配在栈上,哪些不行呢?

其实聪明的软件工程师们早就解决了这个问题了,他们新造了一个名字:逃逸分析。

那么什么是逃逸分析呢?

从字面意思上来讲,逃逸分析的目的是判断对象的作用域是否有可能逃出函数体。例如下面的代码就显示了一个逃逸的对象:

private static User user; private static void hello(){ u = new User(); u.name = "java.top.select"; u.website = "http://www.shuyi.me"; }

对象实例 user 是类的成员变量,可以被任何线程访问,因此它属于逃逸对象。但如果我们将代码稍微改动一下,该对象就可以线程非逃逸的了。

private static void hello(){ User u = new User(); u.name = "java.top.select"; u.website = "http://www.shuyi.me"; }

可以看到 user 实例作用域只在 hello 函数中,不会被其他线程访问到,也不会访问。所以该 user 实例对象的作用域只在该函数中,因此它并未发生逃逸。对于这样的情况,虚拟机就有可能将其分配在栈上,而不在堆上。

看到这里,我相信许多人都应该明白了什么是栈上分配了。简单点说,就是将本来应该分配在堆中的对象,让其分配在线程私有的栈上。通过这种方式,减少垃圾回收的压力,提高虚拟机的运行效率。

TLAB

TLAB(Thread Local Allocation Buffer),即线程本地分配缓存。这是一块线程专用的内存分配区域,TLAB 占用的是 eden 区的空间。在 TLAB 启用的情况下(默认开启),JVM 会为每一个线程分配一块 TLAB 区域。

那么问什么需要 TLAB 呢?这是为了加速对象的分配!

由于对象一般分配在堆上,而堆事线程共用的,因此可能会有多个线程在堆上申请空间,而每一次的对象分配都必须线程同步,这样会降低内存分配的效率。

考虑到对象分配是非常常见的操作,于是 JVM 使用 TLAB 这样的线程转悠区域来避免多线程冲突,提高对象分配效率。

为了不至于导致 Eden 区被填充满,因此 TLAB 空间一般不会太大。因此大对象有可能无法在 TLAB 分配,只能直接分配到堆上。这其实是一种折中的设计哲学,因为大多数分配的对象都比较小,因此 TLAB 空间能满足大多数的需求。

PLAB

PLAB(Promotion Local Allocation Buffers),即晋升本地分配缓存。PLAB 的作用于 TLAB 类似,都是为了加速对象分配效率,避免多线程竞争而诞生的。只不过 PLAB 是应用于对象晋升到 Survivor 区或老年代。与 TLAB 类似,每个线程都有独立的 PLAB 区。

对象内存分配流程

对于栈上分配与 TLAB 而言,其是有一定关系的。在进行对象内存分配的时候,首先会尝试进行栈上分配,接着尝试进行 TLAB 分配,接着判断是否可以直接进入老年代,最后不行的话再在 eden 区分配,如下图所示。

图片来自网络

总结

了解完栈上分配、TLAB、PLAB 之后,我们基本上可以清晰地回答如下问题。

什么是栈上分配,它解决什么问题?

栈上分配指的是对象直接在线程栈帧中进行分配,而不在堆中分配。它主要是为了解决多线程对象分配的低效问题,通过在栈上分配内存,避免了多线程之间的冲突,提高了对象的分配效率。但要注意的是,其只能分配较小对象,并且该对象必须不被其他对象线程引用。

什么是 TLAB,它解决什么问题?

TLAB 指的是线程本地分配缓存,其对应 Eden 区的某个区域,但这块区域只可以被该线程使用。

栈上分配和 TLAB 有啥区别?

TLAB 可以理解成是栈上分配的升级版本。栈上分配的对象只能被线程本身访问,但 TLAB 的对象可以被其他对象读取,但应该无法操作。通过 TLAB,它解决了部分需要多线程访问的对象分配效率问题,进一步提升了 JVM 的对象分配效率。

什么是 PLAB,它解决了什么问题?

PLAB 是为了在对象晋升到 Survivor 区或老年代的时候,提升对象的分配效率。其优化思路与 TLAB 类似,只是应用的地方不同。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 8:21:18

Spring Boot 升级到2.7的踩坑总结

这篇文章分享一下Spring Boot 升级到2.7的踩坑总结,还是挺全面的,希望对大家有所帮助~说明2.7.2为2.x的最后一个稳定版本。3开始最低要求 Java 17,所以暂时不到3.x。以下的处理方法主要针对我们的项目,可能并不通用。1、hibernate…

作者头像 李华
网站建设 2026/4/23 8:22:18

生成引擎优化(GEO)在内容创作与用户体验提升中的创新应用分析

生成引擎优化(GEO)正日益成为内容创作的重要工具。它不仅通过智能化技术为创作者提供高效的文本生成手段,还帮助优化内容的相关性和趣味性。借助GEO,创作者能够更加精准地满足用户的需求,从而提升整体用户体验。在这一…

作者头像 李华
网站建设 2026/4/23 8:21:44

城市多模型式交通网络仿真分析软件界面设计

01项目背景随着城市化进程加速,城市交通系统日益复杂,亟需高效、精准的管理工具。该项目旨在通过构建多模式、多尺度的交通仿真模型,精准模拟城市交通运行状况,为规划者、管理者提供科学依据。面对交通拥堵、排放污染等挑战&#…

作者头像 李华
网站建设 2026/4/23 8:21:24

2026年降AIGC保留原文实测:8000字论文改完意思一字不差

2026年降AIGC保留原文实测:8000字论文改完意思一字不差 先说一件让我血压飙升的事。今年1月份,一个研三的朋友找我帮忙看他的论文,他用某个降AI工具处理了一篇8000字的文献综述。打开一看,好家伙,AI率确实从91%降到了…

作者头像 李华
网站建设 2026/4/23 9:58:06

教师人事系统:让教职工管理更轻松高效

✅作者简介:合肥自友科技 📌核心产品:智慧校园平台(包括教工管理、学工管理、教务管理、考务管理、后勤管理、德育管理、资产管理、公寓管理、实习管理、就业管理、离校管理、科研平台、档案管理、学生平台等26个子平台) 。公司所有人员均有多…

作者头像 李华
网站建设 2026/4/18 11:13:08

小白程序员轻松入门大模型:AI大语言模型排行榜

SuperCLUE 通用榜中文语言理解测评基准CLUE(The Chinese Language Understanding Evaluation)是致力于科学、客观、中立的语言模型评测基准,发起于2019年。陆续推出CLUE、FewCLUE、KgCLUE、DataCLUE等广为引用的测评基准。SuperCLUE是大模型时…

作者头像 李华