tlab java_浅析java中的TLAB
好久,好久....沒(méi)有更博客了。這一次利用閑暇時(shí)間,來(lái)扯一下關(guān)于JVM中的TLAB。
什么是TLAB?它是干什么的?咋們先拋開(kāi)這個(gè)問(wèn)題,一切的開(kāi)始得從new對(duì)象到指針碰撞開(kāi)始講起。
new對(duì)象與指針碰撞
new對(duì)象怎么就出問(wèn)題了呢?
java中我們要?jiǎng)?chuàng)建一個(gè)對(duì)象,用關(guān)鍵字new就可以了。但是,在我們?nèi)粘V?#xff0c;有很多生命周期很短的對(duì)象。比如:
public void dome(){
User user=new user();
user.sayhi();
}
這種對(duì)象的作用域都不會(huì)逃逸出方法外,也就是說(shuō)該對(duì)象的生命周期會(huì)隨著方法的調(diào)用開(kāi)始而開(kāi)始,方法的調(diào)用結(jié)束而結(jié)束。
假設(shè)JVM所有的對(duì)象都放在堆內(nèi)存中(為什么用假設(shè),因?yàn)镴VM并不是這樣)一旦方法結(jié)束,沒(méi)有了指向該對(duì)象的引用,該對(duì)象就需要被GC回收,如果存在很多這樣的情況,對(duì)GC來(lái)說(shuō)壓力山大呀。
那么什么又是指針碰撞呢?
假設(shè)JVM虛擬機(jī)上,堆內(nèi)存都是規(guī)整的。堆內(nèi)存被一個(gè)指針一分為二。指針的左邊都被塞滿(mǎn)了對(duì)象,指針的右變是未使用的區(qū)域。每一次有新的對(duì)象創(chuàng)建,指針就會(huì)向右移動(dòng)一個(gè)對(duì)象size的距離。這就被稱(chēng)為指針碰撞。
圖1.png
好,問(wèn)題來(lái)了。如果我們用多線(xiàn)程執(zhí)行剛才的dome方法,一個(gè)線(xiàn)程正在給A對(duì)象分配內(nèi)存,指針還沒(méi)有來(lái)的及修改,同時(shí)為B對(duì)象分配內(nèi)存的線(xiàn)程,仍引用這之前的指針指向。這樣就出現(xiàn)毛病了。
(要注意的是,上面兩種情況解決方案不止一個(gè),我今天主要是講TLAB,其他方案自行查詢(xún))
TLAB的出現(xiàn)
我們現(xiàn)在已經(jīng)搞清楚,我們出現(xiàn)了哪些問(wèn)題。我在為大家介紹一下今天的主角。
TLAB的全稱(chēng)是Thread Local Allocation Buffer,即線(xiàn)程本地分配緩存區(qū),這是一個(gè)線(xiàn)程專(zhuān)用的內(nèi)存分配區(qū)域。
如果設(shè)置了虛擬機(jī)參數(shù) -XX:UseTLAB,在線(xiàn)程初始化時(shí),同時(shí)也會(huì)申請(qǐng)一塊指定大小的內(nèi)存,只給當(dāng)前線(xiàn)程使用,這樣每個(gè)線(xiàn)程都單獨(dú)擁有一個(gè)空間,如果需要分配內(nèi)存,就在自己的空間上分配,這樣就不存在競(jìng)爭(zhēng)的情況,可以大大提升分配效率。
TLAB空間的內(nèi)存非常小,缺省情況下僅占有整個(gè)Eden空間的1%,也可以通過(guò)選項(xiàng)-XX:TLABWasteTargetPercent設(shè)置TLAB空間所占用Eden空間的百分比大小。
TLAB的本質(zhì)其實(shí)是三個(gè)指針管理的區(qū)域:start,top 和 end,每個(gè)線(xiàn)程都會(huì)從Eden分配一塊空間,例如說(shuō)100KB,作為自己的TLAB,其中 start 和 end 是占位用的,標(biāo)識(shí)出 eden 里被這個(gè) TLAB 所管理的區(qū)域,卡住eden里的一塊空間不讓其它線(xiàn)程來(lái)這里分配。
TLAB只是讓每個(gè)線(xiàn)程有私有的分配指針,但底下存對(duì)象的內(nèi)存空間還是給所有線(xiàn)程訪(fǎng)問(wèn)的,只是其它線(xiàn)程無(wú)法在這個(gè)區(qū)域分配而已。從這一點(diǎn)看,它被翻譯為 線(xiàn)程私有分配區(qū) 更為合理一點(diǎn)
當(dāng)一個(gè)TLAB用滿(mǎn)(分配指針top撞上分配極限end了),就新申請(qǐng)一個(gè)TLAB,而在老TLAB里的對(duì)象還留在原地什么都不用管——它們無(wú)法感知自己是否是曾經(jīng)從TLAB分配出來(lái)的,而只關(guān)心自己是在eden里分配的。
TLAB的缺點(diǎn)
事務(wù)總不是完美的,TLAB也又自己的缺點(diǎn)。因?yàn)門(mén)LAB通常很小,所以放不下大對(duì)象。
1,TLAB空間大小是固定的,但是這時(shí)候一個(gè)大對(duì)象,我TLAB剩余的空間已經(jīng)容不下它了。(比如100kb的TLAB,來(lái)了個(gè)110KB的對(duì)象)
2,TLAB空間還剩一點(diǎn)點(diǎn)沒(méi)有用到,有點(diǎn)舍不得。(比如100kb的TLAB,裝了80KB,又來(lái)了個(gè)30KB的對(duì)象)
所以JVM開(kāi)發(fā)人員做了以下處理,設(shè)置了最大浪費(fèi)空間。
當(dāng)剩余的空間小于最大浪費(fèi)空間,那該TLAB屬于的線(xiàn)程在重新向Eden區(qū)申請(qǐng)一個(gè)TLAB空間。進(jìn)行對(duì)象創(chuàng)建,還是空間不夠,那你這個(gè)對(duì)象太大了,去Eden區(qū)直接創(chuàng)建吧!
當(dāng)剩余的空間大于最大浪費(fèi)空間,那這個(gè)大對(duì)象請(qǐng)你直接去Eden區(qū)創(chuàng)建,我TLAB放不下沒(méi)有使用完的空間。
當(dāng)然,又回造成新的病垢。
3,Eden空間夠的時(shí)候,你再次申請(qǐng)TLAB沒(méi)問(wèn)題,我不夠了,Heap的Eden區(qū)要開(kāi)始GC,
4,TLAB允許浪費(fèi)空間,導(dǎo)致Eden區(qū)空間不連續(xù),積少成多。以后還要人幫忙打理。
總結(jié)
以上是生活随笔為你收集整理的tlab java_浅析java中的TLAB的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: recycleviewitem 列表加载
- 下一篇: flutter天气_牛笔!自己用Flut