本地线程分配缓冲_线程本地分配缓冲区
本地線程分配緩沖
最近,我一直在研究遭受嚴重性能問題的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
本地線程分配緩沖
總結
以上是生活随笔為你收集整理的本地线程分配缓冲_线程本地分配缓冲区的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蓝光膜真的护眼吗蓝光膜真能护眼吗
- 下一篇: 论我怎么也开不了机的电脑电脑怎么都开不了