网站定位方案,国外优秀网页设计欣赏,网站制作制作,上海微网站开发最近#xff0c;我一直在研究遭受严重性能问题的Java应用程序。 在许多问题中#xff0c;真正引起我注意的一个问题是新对象的分配速率相对较低#xff08;应用程序分配了大量的相当大的对象#xff09;。 后来发现#xff0c;原因是在TLAB之外发生了大量分配。 什么是TL… 最近我一直在研究遭受严重性能问题的Java应用程序。 在许多问题中真正引起我注意的一个问题是新对象的分配速率相对较低应用程序分配了大量的相当大的对象。 后来发现原因是在TLAB之外发生了大量分配。 什么是TLAB 在Java中新对象在Eden中分配。 这是线程之间共享的内存空间。 如果考虑到多个线程可以同时分配新对象那么显然需要某种同步机制。 怎么解决呢 分配队列 某种互斥锁 即使这些是不错的解决方案也有更好的解决方案。 这就是TLAB发挥作用的地方。 TLAB代表线程本地分配缓冲区它是Eden内部的一个专为线程分配的区域。 换句话说只有一个线程可以在该区域分配新对象。 每个线程都有自己的TLAB。 因此只要在TLAB中分配对象就不需要任何类型的同步。 在TLAB内部进行分配很简单 指针缓冲 这就是为什么有时将其称为指针缓冲分配 –因此将使用下一个空闲内存地址。 TLAB变得满满的 可以想象TLAB不是无限的在某些时候它开始变满。 如果线程需要分配一个不适合当前TLAB的新对象因为它几乎已满则会发生两件事 线程获取新的TLAB 该对象在TLAB之外分配 JVM根据几个参数决定将要发生的情况。 如果选择了第一个选项则线程的当前TLAB将“退休”并且分配将在新的TLAB中完成。 在第二种情况下分配是在Eden的共享区域中完成的这就是为什么需要某种同步的原因。 通常同步是有代价的。 物体太大 默认情况下将针对每个线程分别动态调整TLAB的大小。 根据Eden的大小线程数及其分配率重新计算TLAB的大小。 更改它们可能会影响TLAB的规模-但是由于分配率通常会有所不同因此没有简单的公式可以解决。 当线程需要分配一个永远无法放入TLAB的大对象例如大数组时它将在Eden的共享区域中分配这又意味着同步。 这正是我的应用程序中正在发生的事情。 由于某些对象太大因此它们从未在TLAB中分配。 在TLAB之外分配一些对象不一定是一件坏事–这是在次要GC之前发生的典型情况。 问题是与TLAB内部相比TLAB外部存在大量分配。 在这种情况下有两个可用选项 使物体变小 尝试调整TLAB尺寸 就我而言手动调整TLAB大小不是最佳选择。 众所周知只有少数对象类型在TLAB之外分配。 通常修复代码是最好的选择。 在我将对象显着减小之后它们已装入TLAB并且TLAB内部分配给TLAB外部分配的比率恢复正常。 翻译自: https://www.javacodegeeks.com/2019/03/thread-local-allocation-buffers.html