本地线程分配缓冲_线程本地分配缓冲区
本地線(xiàn)程分配緩沖
最近,我一直在研究遭受?chē)?yán)重性能問(wèn)題的Java應(yīng)用程序。 在許多問(wèn)題中,真正引起我注意的一個(gè)問(wèn)題是新對(duì)象的分配速度相對(duì)較慢(應(yīng)用程序分配了大量的相當(dāng)大的對(duì)象)。 后來(lái)發(fā)現(xiàn),原因是大量的分配發(fā)生在TLAB之外。
什么是TLAB?
在Java中,新對(duì)象在Eden中分配。 這是線(xiàn)程之間共享的內(nèi)存空間。 如果考慮到多個(gè)線(xiàn)程可以同時(shí)分配新對(duì)象,那么顯然需要某種同步機(jī)制。 怎么解決呢? 分配隊(duì)列? 某種互斥鎖? 即使這些是不錯(cuò)的解決方案,也有更好的解決方案。 這是TLAB發(fā)揮作用的地方。 TLAB代表線(xiàn)程本地分配緩沖區(qū),它是Eden內(nèi)部的一個(gè)專(zhuān)為線(xiàn)程分配的區(qū)域。 換句話(huà)說(shuō),只有一個(gè)線(xiàn)程可以在該區(qū)域中分配新對(duì)象。 每個(gè)線(xiàn)程都有自己的TLAB。 因此,只要在TLAB中分配對(duì)象,就不需要任何類(lèi)型的同步。 在TLAB內(nèi)部進(jìn)行分配很簡(jiǎn)單
指針緩沖 (這就是為什么有時(shí)稱(chēng)為指針緩沖分配)的原因
–因此將使用下一個(gè)空閑內(nèi)存地址。
TLAB變得滿(mǎn)滿(mǎn)的
可以想象,TLAB不是無(wú)限的,在某些時(shí)候它開(kāi)始變滿(mǎn)。 如果線(xiàn)程需要分配一個(gè)不適合當(dāng)前TLAB的新對(duì)象(因?yàn)樗鼛缀跻褲M(mǎn)),則會(huì)發(fā)生兩件事:
- 線(xiàn)程獲取新的TLAB
- 該對(duì)象在TLAB之外分配
JVM根據(jù)幾個(gè)參數(shù)決定將要發(fā)生的情況。 如果選擇了第一個(gè)選項(xiàng),則線(xiàn)程的當(dāng)前TLAB將“退休”,并且分配將在新的TLAB中完成。 在第二種情況下,分配是在Eden的共享區(qū)域中完成的,這就是為什么需要某種同步的原因。 通常,同步是有代價(jià)的。
物體太大
默認(rèn)情況下,將針對(duì)每個(gè)線(xiàn)程分別動(dòng)態(tài)調(diào)整TLAB的大小。 根據(jù)Eden的大小,線(xiàn)程數(shù)及其分配率重新計(jì)算TLAB的大小。 更改它們可能會(huì)影響TLAB的規(guī)模-但是,由于分配率通常會(huì)有所不同,因此沒(méi)有簡(jiǎn)單的公式可以解決。 當(dāng)線(xiàn)程需要分配一個(gè)永遠(yuǎn)無(wú)法容納在TLAB中的大對(duì)象(例如,大數(shù)組)時(shí),它將在Eden的共享區(qū)域中分配,這又意味著同步。 這正是我的應(yīng)用程序中正在發(fā)生的事情。 由于某些對(duì)象太大,因此它們從未在TLAB中分配。
在TLAB之外分配一些對(duì)象并不一定是一件壞事–這是在次要GC之前發(fā)生的典型情況。 問(wèn)題是,與TLAB內(nèi)部相比,TLAB外部有大量分配。 在這種情況下,有兩個(gè)可用選項(xiàng):
- 縮小物體
- 嘗試調(diào)整TLAB尺寸
就我而言,手動(dòng)調(diào)整TLAB大小不是最佳選擇。 眾所周知,只有很少的對(duì)象類(lèi)型在TLAB之外分配。 通常,修復(fù)代碼是最好的選擇。 在我將對(duì)象顯著縮小之后,它們已裝入TLAB,并且TLAB內(nèi)部分配給TLAB外部分配的比率恢復(fù)正常。
翻譯自: https://www.javacodegeeks.com/2019/03/thread-local-allocation-buffers.html
本地線(xiàn)程分配緩沖
總結(jié)
以上是生活随笔為你收集整理的本地线程分配缓冲_线程本地分配缓冲区的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 蓝光膜真的护眼吗蓝光膜真能护眼吗
- 下一篇: 论我怎么也开不了机的电脑电脑怎么都开不了