2024-01-25  阅读(6)
原文作者:hashcon 原文地址: https://zhanghaoxin.blog.csdn.net/article/details/113625614

6. JVM 中的期望计算 EMA

在上面提到的 TLAB 大小设计的时候,我们经常提到期望。这个期望是根据历史数据计算得出的,也就是 每次输入采样值,根据历史采样值得出最新的期望值 。不仅 TLAB 用到了这种期望计算,GC 和 JIT 等等 JVM 机制中都用到了。这里我们来看一种 TLAB 中经常用到的 EMA(Exponential Moving Average 指数平均数) 算法:

202401252013317761.png

EMA 算法的核心在于设置合适的 最小权重 ,我们假设一个场景:首先采样100个 100(算法中的前 100 个是为了排除不稳定的干扰,我们这里直接忽略前 100 个采样),之后采样 50 个 2,最后采样 50 个 200,对于不同的 最小权重 ,来看一下变化曲线。

202401252013321512.png

可以看出, 最小权重越大 ,变化得越快,受 历史数据影响越小 。根据应用设置合适的 最小权重 ,可以让你的期望更加理想。

这块对应的源代码:gcUtil.hppAdaptiveWeightedAverage 类。

7. TLAB 相关的 JVM 参数

这里仅仅是列出来,并附上简介,看不懂没关系,之后会有详细分析,帮助你理解每一个参数。等你理解后,这个小章节就是你的工具书啦~~
以下参数以及默认值基于 OpenJDK 17

7.1. TLABStats(已过期)

从 Java 12 开始已过期,目前已经没有相关的逻辑了。之前是用于 TLAB 统计数据从而更好地伸缩 TLAB 但是性能消耗相对较大,但是现在主要通过 EMA 计算了。

7.2. UseTLAB

说明 :是否启用 TLAB,默认是启用的。

默认 :true

举例 :如果想关闭:-XX:-UseTLAB

7.3. ZeroTLAB

说明 :是否将新创建的 TLAB 内的所有字节归零。我们创建一个类的时候,类的 field 是有默认值的,例如 boolean 是 false,int 是 0 等等,实现的方式就是对分配好的内存空间赋 0。设置 ZeroTLAB 为 true 代表在 TLAB 申请好的时候就赋 0 ,否则会在分配对象并初始化的时候赋 0.讲道理, 由于 TLAB 分配的时候会涉及到 Allocation Prefetch 优化 CPU 缓存,在 TLAB 分配好之后立刻更新赋 0 对于 CPU 缓存应该是更友好的 ,并且,如果 TLAB 没有用满,填充的 dummy object 其实依然是 0 数组,相当于大部分不用改。这么看来,开启应该更好。但是ZeroTLAB 默认还是不开启的。

默认 :false

举例-XX:+ZeroTLAB

7.4. ResizeTLAB

说明 :TLAB 是否是可变的,默认为是,也就是会根据线程历史分配数据相关 EMA 计算出每次期望 TLAB 大小并以这个大小为准申请 TLAB。

默认 :true

举例 :如果想关闭:-XX:-ResizeTLAB

7.5. TLABSize

说明 :初始 TLAB 大小。单位是字节

默认 :0, 0 就是不主动设置 TLAB 初始大小,而是通过 JVM 自己计算每一个线程的初始大小

举例-XX:TLABSize=65536

7.6. MinTLABSize

说明 :最小 TLAB 大小。单位是字节

默认 :2048

举例-XX:TLABSize=4096

7.7. TLABAllocationWeight

说明 : TLAB 初始大小计算和线程数量有关,但是线程是动态创建销毁的。所以需要基于历史线程个数推测接下来的线程个数来计算 TLAB 大小。一般 JVM 内像这种预测函数都采用了 EMA 。 这个参数就是 图06 中的最小权重 ,权重越高,最近的数据占比影响越大。TLAB 重新计算大小是根据分配比例,分配比例也是采用了 EMA 算法,最小权重也是 TLABAllocationWeight

默认 :35

举例-XX:TLABAllocationWeight=70

7.8. TLABWasteTargetPercent

说明 :TLAB 的大小计算涉及到了 Eden 区的大小以及可以浪费的比率。 TLAB 浪费 指的是上面提到的重新申请新的 TLAB 的时候老的 TLAB 没有分配的空间。这个参数其实就是 TLAB 浪费占用 Eden 的百分比,这个参数的作用会在接下来的原理说明内详细说明

默认 :1

举例-XX:TLABWasteTargetPercent=10

7.9. TLABRefillWasteFraction

说明 : 初始 最大浪费空间限制 计算参数,初始 最大浪费空间限制 = 当前期望 TLAB 大小 / TLABRefillWasteFraction

默认 :64

举例-XX:TLABRefillWasteFraction=32

7.10. TLABWasteIncrement

说明最大浪费空间限制并不是不变的 ,在发生 TLAB 缓慢分配的时候(也就是当前 TLAB 空间不足以分配的时候),会增加最大浪费空间限制。这个参数就是 TLAB 缓慢分配时允许的 TLAB 浪费增量。单位不是字节,而是 MarkWord 个数,也就是 Java 堆的内存最小单元,64 位虚拟机的情况下,MarkWord 大小为 3 字节。

默认 :4

举例-XX:TLABWasteIncrement=4


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文