福哥答案2020-10-03:#福大大架構師每日一題#算法
簡單回答:
satb: snapshot-at-the-beginning,快照。
tlab:thread local allocation buffer,線程本地分配緩衝。架構
中級回答:
satb: snapshot-at-the-beginning,快照。
mark的過程就是遍歷heap標記live object,採用的是三色標記算法,這三種顏色爲white(表示還未訪問到)、gray(訪問到可是它用到的引用尚未徹底掃描)、black(訪問到並且其用到的引用已經徹底掃描完),整個三色標記算法就是從GC roots出發遍歷heap,針對可達對象先標記white爲gray,而後再標記gray爲black;遍歷完成以後全部可達對象都是black的,全部white都是能夠回收的。
SATB僅僅對於在marking開始階段進行"snapshot"(marked all reachable at mark start),可是concurrent的時候併發修改可能形成對象漏標記,好比
①.對black新引用了一個white對象,而後又從gray對象中刪除了對該white對象的引用,這樣會形成了該white對象漏標記。
②.對black新引用了一個white對象,而後從gray對象刪了一個引用該white對象的white對象,這樣也會形成了該white對象漏標記。
③.對black新引用了一個剛new出來的white對象,沒有其餘gray對象引用該white對象,這樣也會形成了該white對象漏標記。
對於三色算法在concurrent的時候可能產生的漏標記問題,SATB在marking階段中,對於從gray對象移除的目標引用對象標記爲gray,對於black引用的新產生的對象標記爲black;因爲是在開始的時候進行snapshot,於是可能存在Floating Garbage。併發
tlab:thread local allocation buffer,線程本地分配緩衝。
把內存分配的動做按照線程劃分在不一樣的空間之中進行,即每一個線程在 Java 堆中預先分配一小塊私有內存,也就是本地線程分配緩衝(Thread LocalAllocationBuffer,TLAB),JVM 在線程初始化時,同時也會申請一塊指定大小的內存,只給當前線程使用,這樣每一個線程都單獨擁有一個 Buffer,若是 須要分配內存,就在本身的 Buffer 上分配,這樣就不存在競爭的狀況,能夠大大提高分配效率,當 Buffer 容量不夠的時候,再從新從 Eden 區域申請一塊 繼續使用。
TLAB 的目的是在爲新對象分配內存空間時,讓每一個 Java 應用線程能在使用本身專屬的分配指針來分配空間,減小同步開銷。
TLAB 只是讓每一個線程有私有的分配指針,但底下存對象的內存空間仍是給全部線程訪問的,只是其它線程沒法在這個區域分配而已。當一個 TLAB 用滿(分 配指針 top 撞上分配極限 end 了),就新申請一個 TLAB。url
評論.net