JVM堆內存結構淺析

Java 1.2以上的版本對jvm內存進行了分代管理,圖示如下:

         JVM將Heap分爲NewGeneration和Old Generation(或Tenured Generation)兩塊來進行管理:


1.        New Generation

又稱爲新生代,程序中新建的對象都將分配到新生代中,新生代又由Eden Space和兩塊Survivor Space構成,可通過-Xmn參數來指定其大小,Eden Space的大小和兩塊Survivor Space的大小比例默認爲8,即當New Generation的大小爲10M時,Eden Space的大小爲8M,兩塊Survivor Space各佔1M,這個比例可通過-XX:SurvivorRatio來指定。

2.        Old Generation

又稱爲舊生代,用於存放程序中經過幾次垃圾回收還存活的對象,例如緩存的對象等,舊生代所佔用的內存大小即爲-Xmx指定的大小減去-Xmn指定的大小。

堆是JVM中所有線程共享的,因此在其上進行對象內存的分配均需要進行加鎖,這也導致了new對象的開銷是比較大的,鑑於這樣的原因,Sun Hotspot JVM爲了提升對象內存分配的效率,對於所創建的線程都會分配一塊獨立的空間,這塊空間又稱爲TLAB(Thread Local Allocation Buffer),其大小由JVM根據運行的情況計算而得,在TLAB上分配對象時不需要加鎖,因此JVM在給線程的對象分配內存時會盡量的在TLAB上分配,在這種情況下JVM中分配對象內存的性能和C基本是一樣高效的,但如果對象過大的話則仍然是直接使用堆空間分配,TLAB僅作用於新生代的Eden Space,因此在編寫Java程序時,通常多個小的對象比大的對象分配起來更加高效,但這種方法同時也帶來了兩個問題,一是空間的浪費,二是對象內存的回收上仍然沒法做到像Stack那麼高效,同時也會增加回收時的資源的消耗,可通過在啓動參數上增加-XX:+PrintTLAB來查看TLAB這塊的使用情況。

當然堆內存是java最活躍的數據及對象存放處,關於它的分配及垃圾回收有不同的實現及策略,後期我們將重點介紹和關注。

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