原理:根據垃圾回收機制的不一樣,Java堆有可能擁有不一樣的結構,最爲常見的就是將整個Java堆分爲新生代和老年代。其中新生代存放新生的對象或者年齡不大的對象,老年代則存放老年對象。新生代分爲eden區、s0區、s1區,s0和s1也被稱爲from和to區域,他們是兩塊大小相等而且能夠互換角色的空間。絕大多數狀況下,對象首先分配在eden區,在新生代回收後,若是對象還存活,則進入s0或s1區,以後每通過一次新生代回收,若是對象存活則它的年齡就加1,對象達到必定的年齡後,則進入老年代。算法
新生代:剛new出來不久的對象,不常常使用 會被優先回收 爲堆內存的1/3或者1/4,採用複製算法實現
老年代:常常被使用的對象。使用15次後就會放入老年代中 比新生代優先級低 不會優先回收 若是老年代也不常常使用也會被回收,採用標記壓縮算法(也叫標記整理算法)數組
即把內存分紅相等的AB兩塊,每次只使用其中的一塊。好比當A內存使用完後,就把A中還存活着的對象複製到另一塊內存中去(B),而後再把已經使用過的內存清理掉。優勢:這樣就不用考慮內存碎片的問題了。缺點:內存減半,代價略高。優化
複製算法當存活的實例多的時候,就須要大量複製,效率不高,不適合老年代。那麼就能夠採用標記-整理算法。也就是先標記,而後對存活的對象進行移動,所有移動到一端,而後再對其它的內存進行清理。日誌
設置新生代比例參數
參數: -Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC -XX:NewRatio=2對象
堆的參數配置
-XX:+PrintGC 每次觸發GC的時候打印相關日誌
-XX:+UseSerialGC 串行回收
-XX:+PrintGCDetails 更詳細的GC日誌
-Xms 堆初始值
-Xmx 堆最大可用值
-Xmn 新生代堆最大可用值
-XX:SurvivorRatio 用來設置新生代中eden空間和from/to空間的比例.
含義:-XX:SurvivorRatio=eden/from=den/to
-XX:SurvivorRatio 用來設置新生代中eden空間和from/to空間的比例.生命週期
總結:在實際工做中,咱們能夠直接將初始的堆大小與最大堆大小相等,
這樣的好處是能夠減小程序運行時垃圾回收次數,從而提升效率。內存
儘可能減小垃圾回收的次數,多了的話會影響效率
堆的初始值與堆內存的最大值要保持一致
初始值越小,垃圾回收次數越多(生產環境上面初始值和最大值必定要一致)
針對JVM堆的設置,通常能夠經過-Xms -Xmx限定其最小、最大值,
(1)爲了防止垃圾收集器在最小、最大之間收縮堆而產生額外的時間,咱們一般把最大、最小設置爲相同的值
(2)年輕代和年老代將根據默認的比例(1:2)分配堆內存,能夠經過調整兩者之間的比率NewRadio來調整兩者之間的大小,
也能夠針對回收代,好比年輕代,經過 -XX:newSize -XX:MaxNewSize來設置其絕對大小。
一樣,爲了防止年輕代的堆收縮,咱們一般會把-XX:newSize -XX:MaxNewSize設置爲一樣大小字符串
GC(或Minor GC):收集生命週期短的區域(Young area)。io
Full GC (或Major GC):收集生命週期短的區域(Young area)和生命週期比較長的區域(Old area)對整個堆進行垃圾收集。效率
他們的收集算法不一樣,因此使用的時間也不一樣。
Minor GC後,Eden是空的嗎?
是的,Minor GC會把Eden中的全部存活對象都移到Survivor區域中,若是Survivor區中放不下,那麼剩下的存活對象就被移到Old generation 中。
GC 效率也會比較高,咱們要儘可能減小 Full GC 的次數。 當顯示調用System.gc() 時,gc does a full collection(both young generation and tenured generation).
顯式調用system.gc()會觸發full gc,對象在Eden出生每經歷一次MInor GC後仍然存活,而且能被Survivor容納,就會被移動到Survivor,
並設定年齡爲1.之後在Survivor每"熬過"一次Minor GC,年齡就增長一歲,當年齡超過必定值(15次)就被移動到老年代,MaxTenuringThreshold用於設置年齡閾值,可是若是Survivor空間中相同年齡全部對象大小的總和大於Survivor空間的一半,
年齡大於或等於該年齡的對象就能夠直接進入老年代,無須等到MaxTenuringThreshold中要求的年齡。
大對象直接進入老年代,好比長數組或長字符串,-XX:PretenureSizeThreshold用於設置大於這個值直接在老年代分配。