90% 的 Java 程序员都说不上来的为何 Java 代码越执行越快(2)- TLAB预热[通俗易懂]

90% 的 Java 程序员都说不上来的为何 Java 代码越执行越快(2)- TLAB预热[通俗易懂]经常听到Java性能不如C/C++的言论,也经常听说Java程序需要预热,那么其中主要原因是啥呢?面试的时候谈到JVM,也有很多面试官喜欢问,为啥Java程序越执行越快呢?一般人都能回答上来,类加载,

经常听到 Java 性能不如 C/C++ 的言论,也经常听说 Java 程序需要预热,那么其中主要原因是啥呢

面试的时候谈到 JVM,也有很多面试官喜欢问,为啥 Java 程序越执行越快呢

一般人都能回答上来,类加载,缓存预热等等,但是深入下去,最重要的却没有答上来,今天本系列文章就来帮助大家理解这个问题的关键。本篇文章是 TLAB 预热。

TLAB(Thread Local Allocation Buffer)线程本地分配缓存区,这是一个线程专用的内存分配区域。

image

既然是一个内存分配区域,我们就先要搞清楚 Java 内存大概是如何分配的。

image

我们这里不考虑栈上分配,这些会在 JIT 的章节详细分析,我们这里考虑的是无法栈上分配需要共享的对象

对于 HotSpot JVM 实现,所有的 GC 算法的实现都是一种对于堆内存的管理,也就是都实现了一种堆的抽象,它们都实现了接口 CollectedHeap。当分配一个对象堆内存空间时,在 CollectedHeap 上首先都会检查是否启用了 TLAB,如果启用了,则会尝试 TLAB 分配;如果当前线程的 TLAB 大小足够,那么从线程当前的 TLAB 中分配;如果不够,但是当前 TLAB 剩余空间小于最大浪费空间限制(这是一个动态的值,我们后面会详细分析),则从堆上(一般是 Eden 区) 重新申请一个新的 TLAB 进行分配。否则,直接在 TLAB 外进行分配。TLAB 外的分配策略,不同的 GC 算法不同。例如G1:

  • 如果是 Humongous 对象(对象在超过 Region 一半大小的时候),直接在 Humongous 区域分配(老年代的连续区域)。
  • 根据 Mutator 状况在当前分配下标的 Region 内分配

这里,我们先只关心 TLAB 分配。 对于单线程应用,每次分配内存,会记录上次分配对象内存地址末尾的指针,之后分配对象会从这个指针开始检索分配。这个机制叫做 bump-the-pointer (撞针)。 对于多线程应用来说,内存分配需要考虑线程安全。最直接的想法就是通过全局锁,但是这个性能会很差。为了优化这个性能,我们考虑可以每个线程分配一个线程本地私有的内存池,然后采用 bump-the-pointer 机制进行内存分配。这个线程本地私有的内存池,就是 TLAB。只有 TLAB 满了,再去申请内存的时候,需要扩充 TLAB 或者使用新的 TLAB,这时候才需要锁。这样大大减少了锁使用。

TLAB 初始化

image

TLAB 分配

image

GC 时 TLAB 回收与重计算期望大小

image

为何 Java 代码越执行越快 – TLAB预热

根据之前的分析,每个线程的 TLAB 的大小,会根据线程分配的特性,不断变化并趋于稳定,大小主要是由分配比例 EMA 决定,但是这个采集是需要一定运行次数的。并且 EMA 的前 100 次采集默认是不够稳定的,所以 TLAB 大小也在程序一开始的时候变化频繁。当程序线程趋于稳定,运行一段时间后, 每个线程 TLAB 大小也会趋于稳定并且调整到最适合这个线程对象分配特性的大小。这样,就更接近最理想的只有 Eden 区满了才会 GC,所有 Eden 区的对象都是通过 TLAB 分配的高效分配情况。这就是 Java 代码越执行越快在 TLAB 方面的原因。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13091.html

(0)

相关推荐

  • CentOS_7.6 安装 Redis 6.0.1 以及开启自动启动相关问题[通俗易懂]

    CentOS_7.6 安装 Redis 6.0.1 以及开启自动启动相关问题[通俗易懂]背景 阿里云的 ECS 服务器,什么软件都没有,需要的软件需要自己装。 下载 Redis 下载地址:https://redis.io/download 当前版本 Redis 6.0.1 升级 gcc…

    2023-02-27
    144
  • c语言怎么打中文字_一节课学会c语言

    c语言怎么打中文字_一节课学会c语言关注我比较久的读者都知道了,我妹今年上大一,学校安排的编程语言是 C 语言,这对于一个初学编程的小白来说,并不容易!作为她亲哥的我,肩膀上抗着巨大的责任,那就是尽全力帮助她入门。 前段时间为了她专门调研了一波 IDE(有我俩的合影,快去瞧瞧),最后我比较钟情 Visual St…

    2023-07-16
    107
  • 将Series转换为DataFrame的方法

    将Series转换为DataFrame的方法emSeries/em和emDataFrame/em是Pandas库中两个重要的数据结构。Series是一维的、标记过的数组,可以保存任何数据类型。而DataFrame则是一个表格型的数据结构,可以看作是Series的容器。在实际数据分析中,经常需要使用Series来进行数据处理,但在进一步分析中,需要使用DataFrame更加方便。因此,将Series转换为DataFrame的方法尤为重要。

    2024-05-05
    69
  • Redis知识点(一)[亲测有效]

    Redis知识点(一)[亲测有效]Redis 是什么 总结下 Redis 的定义和特点: Redis 是 C 语言开发的一个开源的(遵从 BSD 协议)高性能键值对(key-value)的内存数据库,可以用作数据库、缓存、消息中间件…

    2023-02-13
    154
  • 使用 Python 进行浏览器自动化

    使用 Python 进行浏览器自动化随着互联网技术的迅猛发展,越来越多的网站和软件需要用户进行人机交互,用户需要不断输入、点击、选择等操作来访问和获取所需要的信息。这种操作不仅繁琐,而且容易出现错误,增加了用户的工作负担,影响工作效率。因此,如何通过自动化技术来代替人工操作,提高工作效率,成为了许多公司和组织关注的焦点。

    2024-08-21
    28
  • 并发执行sql_blockingqueue 多线程

    并发执行sql_blockingqueue 多线程来源:http://www.postgres.cn/docs/11/ 13.2.1. 读已提交隔离级别 读已提交是PostgreSQL中的默认隔离级别。 当一个事务运行使用这个隔离级别时,

    2023-02-26
    141
  • 🚴‍♂️全套MySQL数据库教程_Mysql基础入门教程,零基础小白自学MySQL数据库必备教程☔ #002 # 第二单元 MySQL数据类型、操作表#[亲测有效]

    🚴‍♂️全套MySQL数据库教程_Mysql基础入门教程,零基础小白自学MySQL数据库必备教程☔ #002 # 第二单元 MySQL数据类型、操作表#[亲测有效]二、本单元知识点概述 (Ⅰ)知识点概述 二、本单元教学目标 (Ⅰ)重点知识目标 1.Mysql的数据类型2.如何选择数据类型3.创建表4.修改表5.删除表 (Ⅱ)能力目标 1.熟练创建数据库及删除数据

    2023-04-24
    152
  • P2865 [USACO06NOV]Roadblocks G/【模板】次短路

    P2865 [USACO06NOV]Roadblocks G/【模板】次短路
    不是可持久化可并堆的事么 在spfa/dij的不等式中间加一个判断,看他能不能更新最短路/次短路。 这题不卡spfa是!!! #include

    2023-04-20
    161

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注