關于棧上分配和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,也希望可以為閱讀本文的小伙伴帶來一些幫助吧

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前言 記錄個人在2017年08月的學習和總結,不定期更新 2017-08-02 有序的Map HashMap是無序...
    Kevin_ZGJ閱讀 421評論 0 0
  • 內存溢出和內存泄漏的區別 內存溢出:out of memory,是指程序在申請內存時,沒有足夠的內存空間供其使用,...
    Aimerwhy閱讀 756評論 0 1
  • 終于要放寒假了,手機上接到數學老師通知的 寒假作業。新學校的作業也分成幾等,粗粗一看兒子位列第三等,作業不...
    納蘭格格L閱讀 506評論 6 9
  • 壓力來自于總偏愛內部事務偏愛已經發生的事情而忽視未來,總喜歡危機而忽視機遇。總傾向于急功近利而對真正的現實世界視而...
    悠哉輕創聯盟閱讀 830評論 0 0
  • 人生每天都在面臨著不同的選擇。 今天和朋友逛街買衣服,很喜歡的一件衣服,就因為袖子有點寬選擇了不買,要是原來的我可...
    藍色薔薇A閱讀 237評論 0 0