jvm - 內存空間提到了,建立對象的時候,對象是在堆內存中建立的。但堆內存又分爲新生代和老年代,新生代又細分Eden空間、From Survivor空間、To Survivor空間。咱們建立的類到底在哪裏?jvm
堆內存分爲新生代和老年代,新生代是用於存放使用後準備被回收的對象,老年代是用於存放生命週期比較長的對象。大部分咱們建立的對象,都屬於生命週期比較短的,因此會存放在新生代。新生代又細分Eden空間、From Survivor空間、To Survivor空間,咱們建立的對象,對象優先在Eden分配。
隨着對象的建立,Eden剩餘內存空間愈來愈少,就會觸發Minor GC
,因而Eden的存活對象會放入From Survivor空間。Minor GC
後,新對象依然會往Eden分配。
Eden剩餘內存空間愈來愈少,又會觸發Minor GC
,因而Eden和From Survivor的存活對象會放入To Survivor空間。
性能
在上面的流程中,若是一個對象很大,一直在Survivor空間複製來複制去,那很費性能,因此這些大對象直接進入老年代。能夠用XX:PretenureSizeThreshold來設置這些大對象的閾值。
spa
在上面的流程中,若是一個對象Hello_A,已經經歷了15次Minor GC
還存活在Survivor空間中,那他即將轉移到老年代。這個15能夠經過-XX:MaxTenuringThreshold來設置的,默認是15。虛擬機爲了給對象計算他到底經歷了幾回Minor GC
,會給每一個對象定義了一個對象年齡計數器。若是對象在Eden中通過第一次Minor GC後仍然存活,移動到Survivor空間年齡加1,在Survivor區中每經歷過Minor GC後仍然存活年齡再加1。年齡到了15,就到了老年代。
code
除了年齡達到MaxTenuringThreshold的值,還有另一個方式進入老年代,那就是動態年齡判斷:在Survivor空間中相同年齡全部對象大小的總和大於Survivor空間的一半,年齡大於或等於該年齡的對象就能夠直接進入老年代。
好比Survivor是100M,Hello1和Hello2都是3歲,且總和超過了50M,Hello3是4歲,這個時候,這三個對象都將到老年代。
對象
上面的流程提過,存活的對象都會放入另一個Survivor空間,若是這些存活的對象比Survivor空間還大呢?整個流程以下:blog