JVM記憶體區域劃分Eden Space,Survivor Space,Tenured Gen,Perm Gen
jvm區域總體分兩類,heap區和非heap區。heap區又分:Eden Space(伊甸園)、Survivor Space(倖存者區)、Tenured Gen(老年代-養老區)。 非heap區又分:Code Cache(程式碼快取區)、Perm Gen(永久代)、Jvm Stack(java虛擬機器棧)、Local Method Statck(本地方法棧)。
HotSpot虛擬機器GC演算法採用分代收集演算法:
1、一個人(物件)出來(new 出來)後會在Eden Space(伊甸園)無憂無慮的生活,直到GC到來打破了他們平靜的生活。GC會逐一問清楚每個物件的情況,有沒有錢(此物件的引用)啊,因為GC想賺錢呀,有錢的才可以敲詐嘛。然後富人就會進入Survivor Space(倖存者區),窮人的就直接kill掉。
2、並不是進入Survivor Space(倖存者區)後就保證人身是安全的,但至少可以活段時間。GC會定期(可以自定義)會對這些人進行敲詐,億萬富翁每次都給錢,GC很滿意,就讓其進入了Genured Gen(養老區)。萬元戶經不住幾次敲詐就沒錢了,GC看沒有啥價值啦,就直接kill掉了。
3、進入到養老區的人基本就可以保證人身安全啦,但是億萬富豪有的也會揮霍成窮光蛋,只要錢沒了,GC還是kill掉。
分割槽的目的:新生區由於物件產生的比較多並且大都是朝生夕滅的,所以直接採用標記-清理演算法。而養老區生命力很強,則採用複製演算法,針對不同情況使用不同演算法。
非heap區域中Perm Gen中放著類、方法的定義,jvm Stack區域放著方法引數、局域變數等的引用,方法執行順序按照棧的先入後出方式。
GC工作機制
SUN的jvm記憶體池被劃分為以下幾個部分:
Eden Space (heap)
記憶體最初從這個執行緒池分配給大部分物件。
Survivor Space (heap)
用於儲存在eden space記憶體池中經過垃圾回收後沒有被回收的物件。
Tenured Generation (heap)
用於保持已經在survivor space記憶體池中存在了一段時間的物件。
Permanent Generation (non-heap)
儲存虛擬機器自己的靜態(reflective)資料,例如類(class)和方法(method)物件。Java虛擬機器共享這些類資料。這個區域被分割為只讀的和只寫的。
Code Cache (non-heap)
HotSpot Java虛擬機器包括一個用於編譯和儲存原生代碼(native code)的記憶體,叫做“程式碼快取區”(code cache)。
簡單來講,jvm的記憶體回收過程是這樣的:
物件在Eden Space建立,當Eden Space滿了的時候,gc就把所有在Eden Space中的物件掃描一次,把所有有效的物件複製到第一個Survivor Space,同時把無效的物件所佔用的空間釋放。當Eden Space再次變滿了的時候,就啟動移動程式把Eden Space中有效的物件複製到第二個Survivor Space,同時,也將第一個Survivor Space中的有效物件複製到第二個Survivor Space。如果填充到第二個Survivor Space中的有效物件被第一個Survivor Space或Eden Space中的物件引用,那麼這些物件就是長期存在的,此時這些物件將被複制到Permanent Generation。
若垃圾收集器依據這種小幅度的調整收集不能騰出足夠的空間,就會執行Full GC,此時jvm gc停止所有在堆中執行的執行緒並執行清除動作。