有这篇文章就够了——JVM TLAB 分析(七)

开课吧开课吧锤锤2021-04-21 09:55

点赞
有用
分享分享

    Java编程语言是一种简单、面向对象、分布式、解释型、健壮安全、与系统无关、可移植、高性能、多线程和动态的语言。如今Java已经广泛应用于各个领域的编程开发。

Java

    8.TLAB基本流程

    8.0.如何设计每个线程的TLAB大小

    之前我们提到了引入TLAB要面临的问题以及解决方式,根据这些我们可以这么设计TLAB。

    首先,TLAB的初始大小,应该和每个GC内需要对象分配的线程个数相关。但是,要分配的线程个数并不一定是稳定的,可能这个时间段线程数多,下个阶段线程数就不那么多了,所以,需要用EMA的算法采集每个GC内需要对象分配的线程个数来计算这个个数期望。

    接着,我们最理想的情况下,是每个GC内,所有用来分配对象的内存都处于对应线程的TLAB中。每个GC内用来分配对象的内存从JVM设计上来讲,其实就是Eden区大小。在最理想的情况下,最好只有Eden区满了的时候才会GC,不会有其他原因导致的GC,这样是最高效的情况。Eden区被用光,如果全都是TLAB内分配,也就是Eden区被所有线程的TLAB占满了,这样分配是最快的。

    然后,每轮GC分配内存的线程个数以及大小是不一定的,如果一下子分配一大块会造成浪费,如果太小则会频繁从Eden申请TLAB,降低效率。这个大小比较难以控制,但是我们可以限制每个线程究竟在一轮GC内,最多从Eden申请多少次TLAB,这样对于用户来说更好控制。

    最后,每个线程分配的内存大小,在每轮GC并不一定稳定,只用初始大小来指导之后的TLAB大小,显然不够。我们换个思路,每个线程分配的内存和历史有一定关系因此我们可以从历史分配中推测,所以每个线程也需要采用EMA的算法采集这个线程每次GC分配的内存,用于指导下次期望的TLAB的大小。

    综上所述,我们可以得出这样一个近似的TLAB计算公式:

    每个线程TLAB初始大小=Eden区大小/(线程单个GC轮次内最多从Eden申请多少次TLAB*当前GC分配线程个数EMA)

    GC后,重新计算TLAB大小=Eden区大小/(线程单个GC轮次内最多从Eden申请多少次TLAB*当前GC分配线程个数EMA)

    接下来,我们来详细分析TLAB的整个生命周期的每个流程。

    以上内容由开课吧老师干货满满张哈希提供,更多Java教程尽在开课吧广场Java教程频道。

有用
分享