《深入理解Java虛擬機》一書中有這樣的表述。
對於大多數應用來說,Java堆,是Java虛擬機所管理的內存中最大的一塊兒。Java堆是被所有線程共享的一塊兒內存區域,在虛擬機啓動時創建。此內存區域的唯一目的:就是存放對象實例,及數組都要堆上分配,但是隨着JIT編譯器的發展與逃逸分析技術逐漸成熟,棧上分配,標量替換優化技術將會導致一些微妙的變化發生,所有對象都分配在堆上也漸漸變得不那麼絕對了。
有兩個問題:
1.什麼時JIT編譯器。
2.什麼是逃逸分析技術。
JIT編譯器
just in time Compiler.動態編譯器針對較長被執行的程式碼,進行編譯,優化成原生指令碼。提高運行性能
逃逸分析
虛擬機分析創建對象的使用範圍,並決定是否在堆上分配的一項技術
return sb
return sb.toString();
把對象控制在方法內,沒有逃出當前方法作用域(第二種)。因爲只是在方法中,不需要共享(未逃逸出該方法),對象可能是棧分配的候選,而不是堆的候選。
總結:
爲什麼說隨着jit編譯器的發展與逃逸分析技術逐漸成熟,對象實例不一定在堆上分配。jit編譯器,判斷是分配在堆上,還是棧上。如果時,對象域在方法內,則可以分配到棧上。
但是優化到棧上分配有什麼好處呢?可直接在棧上訪問實例,減少GC次數。
每個棧幀中分配多少內存基本是在類結構確定下來是,是已知的。方法結束,或者線程結束時,內存就自然跟着回收了。
參考博客