關於棧上分配和TLAB的理解

引言

我們知道,一般在java程序中,new的對象是分配在堆空間中的,但是實際的情況是,大部分的new對象會進入堆空間中,而並非是全部的對象,還有另外兩個地方可以存儲new的對象,我們稱之爲棧上分配以及TLAB


棧上分配

爲什麼需要棧上分配

在我們的應用程序中,其實有很多的對象的作用域都不會逃逸出方法外,也就是說該對象的生命週期會隨着方法的調用開始而開始,方法的調用結束而結束,對於這種對象,是不是該考慮將對象不在分配在堆空間中呢?

因爲一旦分配在堆空間中,當方法調用結束,沒有了引用指向該對象,該對象就需要被gc回收,而如果存在大量的這種情況,對gc來說無疑是一種負擔。

什麼是棧上分配

因此,JVM提供了一種叫做棧上分配的概念,針對那些作用域不會逃逸出方法的對象,在分配內存時不在將對象分配在堆內存中,而是將對象屬性打散後分配在棧(線程私有的,屬於棧內存)上,這樣,隨着方法的調用結束,棧空間的回收就會隨着將棧上分配的打散後的對象回收掉,不再給gc增加額外的無用負擔,從而提升應用程序整體的性能

棧上分配如何開啓

棧上分配需要有一定的前提

  • 開啓逃逸分析 (-XX:+DoEscapeAnalysis)

逃逸分析的作用就是分析對象的作用域是否會逃逸出方法之外,再server虛擬機模式下纔可以開啓(jdk1.6默認開啓)

  • 開啓標量替換 (-XX:+EliminateAllocations)

標量替換的作用是允許將對象根據屬性打散後分配再棧上,默認該配置爲開啓

如何查看逃逸分析的篩選結果

可以通過配置 -XX:+PrintEscapeAnalysis 開啓打印逃逸分析篩選結果


TLAB

可能很多人會有疑惑,已經提供了棧上分配,爲什麼還要有什麼TLAB,甚至混淆了兩者之間的差別,包括我自己,之前也存在很多疑惑,下面爲大家揭開原因

爲什麼需要TLAB

我們知道,對象分配在堆上,而堆是一個全局共享的區域,當多個線程同一時刻操作堆內存分配對象空間時,就需要進行同步,而同步帶來的效果就是對象分配效率變差(儘管JVM採用了CAS的形式處理分配失敗的情況),但是對於存在競爭激烈的分配場合仍然會導致效率變差。

什麼是TLAB

全稱叫做:Thread Local Allocation Buffer 即線程本地分配緩存

那麼能不能構造一種線程私有的堆空間,哪怕這塊堆空間特別小,但是只要有,就可以每個線程在分配對象到堆空間時,先分配到自己所屬的那一塊堆空間中,避免同步帶來的效率問題,從而提高分配效率

如何開啓TLAB

JVM默認開啓了TLAB功能,也可以使用-XX: +UseTLAB 顯示開啓

如何觀察TLAB使用情況

JVM提供了-XX:+PrintTLAB 參數打開跟蹤TLAB的使用情況

如何調整TLAB默認大小

-XX:TLABSize 通過該參數指定分配給每一個線程的TLAB空間的大小

總結一下TLAB:

需要TLAB的原因就是提高對象在堆上的分配效率而採用的一種手段,就是給每個線程分配一小塊私有的堆空間,即TLAB是一塊線程私有的堆空間(實際上是Eden區中劃出的)


棧上分配和TLAB對比

名稱 針對點 處於對象分配流程的位置
棧上分配 避免gc無謂負擔 1
TLAB 加速堆上對象的分配 2

對象分配流程圖

圖片摘自實戰Java虛擬機一書

對象分配流程圖

總結

通過以上分析,弄懂了關於棧上分配和TLAB,也希望可以爲閱讀本文的小夥伴帶來一些幫助吧



作者:0愛上1
鏈接:https://www.jianshu.com/p/f1e5e03ed2f8
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章