Java對象在完成正确的堆記憶體空間配置設定時采用二種方式:一種是cas失敗重試,另一種是Tlab。tlab是線程本地配置設定記憶體的英語縮寫,從語義可知是一個線程專用的記憶體配置設定區域,他也存在堆中,但是也獨立于堆中空間。
我們在為一個對象在堆中配置設定空間時,也有其他線程在為對象在堆記憶體配置設定空間,于是就存在空間的競争,在激烈的競争場合記憶體配置設定的效率比較低下,是以考慮以上的情況出現,我們采用TLAB線程專屬空間避免多線程沖突,提高配置設定效率。TlAB也是占用堆記憶體的esdn空間的,在啟用Tlab情況下(預設開啟)虛拟機會為每個線程建立一個配置設定Tlab空間的。TLAB隻是讓每個線程有私有的配置設定指針,但底下存對象的記憶體空間還是給所有線程通路的,隻是其它線程無法在這個區域配置設定而已。
TLAB空間一般是不會太大,則較大對象肯定無法在此配置設定,正是TlAB空間的局限性,對象可能很容易将此空間裝滿。如一個線程,他有100k的TLAB空間,現在已存入對象占用了80k,現在有個30k的對象肯定無法滿足對空間的需求,是以它存在二種解決方式:第一種就是放棄目前的TLAB空間,把他還給堆空間,建立新的TLAB。第二種就是讓這個30k的對象在堆空間配置設定,保留TLAB空間,或許後面會有小于等于20k的對象。
為了解決以上的情況,虛拟機維護了一個refill-waste的值,他表示TLAB允許記憶體浪費的空間。預設是tlab空間的1/64(在運作時可能會自動調整達到最優化)。當新的對象請求時空間記憶體已不足時,會讓目前對象所需占用的空間記憶體和refill-waste比較,若大于rw會在堆中配置設定,保留tlab;小于rw會廢棄目前Tlab空間建立一個配置設定對象。當然這些鬼東西都是可以手動調節,具體參數網上找。
其實對象的大緻配置設定流程:
第一:嘗試棧上配置設定,如不成功第二步。
第二:嘗試tlab配置設定,如不成功第三步。
第三:是否滿足老年代配置設定,如不成功第四步。
第四:edsn配置設定。