有理想的「程序猿」應該知道基於「逃逸分析的棧上分配優化」

什麼是棧上分配?

棧上分配是Java虛擬機提供的一種優化技術。指的是那些線程私有的、不可被其它線程訪問的對象,將他們分配在棧上,而不是堆上。這樣的對象就能隨著棧的銷燬而銷燬,不需要垃圾收集,從而提高性能。

如何進行棧上分配?

棧上分配技術基礎是逃逸分析,逃逸分析的作用是判斷作用域是否可能逃逸出函數體。

有理想的“程序猿”應該知道基於“逃逸分析的棧上分配優化”

上面代碼中包含兩個函數,test1中包含成員變量user,該成員變量可能被其它任何線程訪問,所以屬於逃逸對象。test2中的user以局部變量形式存在,並且沒有被返回或者任何形式的公開,因此屬於非逃逸對象,這樣的對象虛擬機會很有可能將其分配在棧上。

如何證明進行了棧上分配?

  • 上面代碼加入測試環節,分別運行test1、test2函數1億次,這樣累計創建的User實例所需內存將超過1G。當我們設置堆內存小於該值,如果沒有進行棧上分配,必定會頻繁進行GC。
有理想的“程序猿”應該知道基於“逃逸分析的棧上分配優化”

  • 設置JVM參數如下:-server -Xmx10m -Xms10m -XX:+PrintGC -XX:+DoEscapeAnalysis -XX:-UseTLAB -XX:+EliminateAllocations
有理想的“程序猿”應該知道基於“逃逸分析的棧上分配優化”

-server(Server模式才能進行逃逸分析)

-Xmx10m(堆最大空間10m)

-Xms10m(堆初始空間10m)

-XX:+PrintGC(打印GC日誌)

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

-XX:-UseTLAB(關閉TLAB)

-XX:+EliminateAllocations(開啟標量替換,允許將對象打散分配在棧上。比如User對象有兩個屬性name、age,那麼將這兩個屬性當作兩個獨立的局部變量分配在棧上)

  • 運行test1函數結果如下
有理想的“程序猿”應該知道基於“逃逸分析的棧上分配優化”

  • 運行test2函數結果如下
有理想的“程序猿”應該知道基於“逃逸分析的棧上分配優化”

  • 從結果可看到,test1函數需要頻繁GC,test2函數由於進行了棧上分配,只進行了3次GC
有理想的“程序猿”應該知道基於“逃逸分析的棧上分配優化”


分享到:


相關文章: