聊聊JVM Young Gen(年轻代)Eden区的线程本地分配缓冲区-TLAB(Thread Local Allocation Buffer)
Posted Dreamer who
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊聊JVM Young Gen(年轻代)Eden区的线程本地分配缓冲区-TLAB(Thread Local Allocation Buffer)相关的知识,希望对你有一定的参考价值。
JVM一般采用分代来管理堆内存,如下图:
逻辑上是连续的,但不同的gc回收算法在实际分配内存时不一定是连续的。
一般大部分对象都在年轻代中的Eden区创建,除个别大对象直接在老年代分配。因为堆是共享的,多个线程可以同时创建对象,为了保证线程安全,Eden区又被分配成一个个线程本地分配缓冲区-TLAB(Thread Local Allocation Buffer)(不排除个别jvm没采用),这个TLAB是线程私有的,每个线程都有自己的TLAB,避免了多线程环境下使用同步技术带来的性能损耗。
当在TLAB因为空间不够,无法分配对象时,根据JVM的相关配置会发生两种情况:
(1)当前线程获取一个新的TLAB
(2)对象被分配在TLAB外,即分配在Eden的共享区,如上图的common area所示区域。
当情况(1)发生时,当前线程的TLAB就“退休了”,对象会分配在新的TLAB。当情况(2)发生时,对象会分配在Eden的共享区,此时需用同步手段保证安全性,所有这种情况下就不可避免的产生了一些性能问题。当TLAB和Eden的共享区都没有空间的时候,年轻代gc回收算法被触发。当年轻代gc回收算法触发后释放的空间还不够的时候,对象会被直接在老年代创建。
和TLAB相关的JVM参数:
-XX:AllocatePrefetchStyle=style
Sets the generated code style for prefetch instructions. The style
argument is an integer from 0 to 3:
Don’t generate prefetch instructions.
Execute prefetch instructions after each allocation. This is the default parameter.
Use the thread-local allocation block (TLAB) watermark pointer to determine when prefetch instructions are executed.
Use BIS instruction on SPARC for allocation prefetch.
Only the Java HotSpot Server VM supports this option.
-XX:+UseTLAB
Enables the use of thread-local allocation blocks (TLABs) in the young generation space. This option is enabled by default. To disable the use of TLABs, specify the option -XX:-UseTLAB
.
-XX:TLABSize=size
Sets the initial size (in bytes) of a thread-local allocation buffer (TLAB). Append the letter k
or K
to indicate kilobytes, m
or M
to indicate megabytes, or g
or G
to indicate gigabytes. If this option is set to 0, then the JVM selects the initial size automatically.
jvm默认为0
- -XX:+PrintTLAB - TLAB summary in GC log - diagnostic. ENABLE!
- -XX:ResizeTLAB - Eables resizing of TLABs,默认启用
- -XX:MinTLABSize
默认ResizeTLAB是启用的,新的TLAB的大小由三个因素决定:应用的线程数量、内存分配率、Eden大小。
对源码感兴趣的可以参考:
https://github.com/openjdk/jdk/blob/jdk8-b120/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp
https://github.com/openjdk/jdk11u/blob/master/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp
参考:
http://geekswithblogs.net/JoshReuben/archive/2016/04/11/jvm-tuning.aspx
https://plumbr.io/handbook/garbage-collection-in-java
https://dzone.com/articles/jrockit-gc-action
https://blog.pythian.com/understanding-java-virtual-machinejvm-architecture-part1/
https://docs.oracle.com/en/java/javase/13/docs/specs/man/java.html#standard-options-for-java
https://alidg.me/blog/2019/6/21/tlab-jvm
https://umumble.com/blogs/java/how-does-jvm-allocate-objects%3F/
http://performantcode.com/2019/03/03/thread-local-allocation-buffers/
以上是关于聊聊JVM Young Gen(年轻代)Eden区的线程本地分配缓冲区-TLAB(Thread Local Allocation Buffer)的主要内容,如果未能解决你的问题,请参考以下文章