1. 程式人生 > >jvm中新生代和老年代的理解

jvm中新生代和老年代的理解

堆用於儲存物件例項及陣列值,可以認為Java中所有通過new建立的物件的記憶體都在此分配,Heap中物件所佔用的記憶體由GC進行回收。為了讓記憶體回收更加高效,Sun JDK從1.2開始對堆採用了分代管理的方式。
1. 新生代(New Generation)

大多數情況下Java程式中新建的物件都從新生代分配記憶體,新生代由Eden Space和兩塊相同大小的Survivor Space(通常又稱為S0和S1或From和To)構成,可通過-Xmn引數來指定新生代的大小,也可通過-XX:SurvivorRatio來調整Eden Space及Survivor Space的大小。不同的GC方式會以不同的方式按此值來劃分Eden Space和Survivor Space,有些GC方式還會根據執行狀況來動態調整Eden、S0、S1的大小。
2. 老年代(Old Generation或Tenuring Generation)

用於存放新生代中經過多次垃圾回收仍然存活的物件,例如快取物件,新建的物件也有可能在老年代上直接分配記憶體。主要有兩種狀況(由不同的GC實現來決定):一種為大物件,可通過在啟動引數上設定-XX:PretenureSizeThreshold=1024(單位為位元組,預設值為0)來代表當物件超過多大時就不在新生代分配,而是直接在老年代分配,此引數在新生代採用Parallel Scavenge GC時無效,Parallel Scavenge GC會根據執行狀況決定什麼物件直接在老年代上分配記憶體;另一種為大的陣列物件,且陣列中無引用外部物件。

新生代和老生代因為結構劃分不一樣,其序列收集器演算法也不一樣
新生代序列收集器
採用stop the world策略,步驟大概是:先從eden區掃描,把存活的物件拷貝到to區,如果to區放不下的物件直接拷貝到old區。再從from區掃描存活物件,如果物件存活次數超過閥值的就移到老年區,其他的移到to區。做完之後from和to區概念互換(from和to只是執行時的概念,其實就對應存活1區和存活2區)。
圖形的表示如下:
回收前:
這裡寫圖片描述


回收後:
這裡寫圖片描述

老生代序列收集器
老生代垃圾回收主要分為三個階段 Mark-sweep-compact
Mark:識別哪些是存活的
Sweep: 識別垃圾,並回收
Compact:滑動活動物件並壓縮到連續空間,碎片整理。