java堆內存的劃分

根據對象的存活率(年齡),Java對內存劃分爲3種:新生代、老年代、永久代

1、新生代:
比如我們在方法中去new一個對象,那這方法調用完畢後,對象就會被回收,這就是一個典型的新生代對象。

現在的商業虛擬機都採用這種收集算法來回收新生代,新生代中的對象98%都是“朝生夕死”的,所以並不需要按照1:1的比例來劃分內存空間,而是將內存分爲一塊比較大的Eden空間和兩塊較小的Survivor空間,每次使用Eden和其中一塊Survivor。當回收時,將Eden和Survivor中還存活着的對象一次性地複製到另外一塊Survivor空間上,最後清理掉Eden和剛纔用過的Survivor空間。HotSpot虛擬機默認Eden和Survivor的大小比例是8:1,也就是說,每次新生代中可用內存空間爲整個新生代容量的90%(80%+10%),只有10%的空間會被浪費。

當然,98%的對象可回收只是一般場景下的數據,我們沒有辦法保證每次回收都只有不多於10%的對象存活,當Survivor空間不夠用時,需要依賴於老年代進行分配擔保,所以大對象直接進入老年代。同時,長期存活的對象將進入老年代(虛擬機給每個對象定義一個年齡計數器)。

這裏寫圖片描述

Minor GC和Full GC:
GC分爲兩種:Minor GC和Full GC

Minor GC:

  Minor GC是發生在新生代中的垃圾收集動作,採用的是複製算法。

對象在Eden和From區出生後,在經過一次Minor GC後,如果對象還存活,並且能夠被to區所容納,那麼在使用複製算法時這些存活對象就會被複制到to區域,然後清理掉Eden區和from區,並將這些對象的年齡設置爲1,以後對象在Survivor區每熬過一次Minor GC,就將對象的年齡+1,當對象的年齡達到某個值時(默認是15歲,可以通過參數 –XX:MaxTenuringThreshold設置),這些對象就會成爲老年代。

但這也是不一定的,對於一些較大的對象(即需要分配一塊較大的連續內存空間)則是直接進入老年代

Full GC:

  Full GC是發生在老年代的垃圾收集動作,採用的是標記-清除/整理算法。

老年代裏的對象幾乎都是在Survivor區熬過來的,不會那麼容易死掉。因此Full GC發生的次數不會有Minor GC那麼頻繁,並且做一次Full GC要比做一次Minor GC的時間要長。

另外,如果採用的是標記-清除算法的話會產生許多碎片,此後如果需要爲較大的對象分配內存空間時,若無法找到足夠的連續的內存空間,就會提前觸發一次GC。

2、老年代:
在新生代中經歷了N次垃圾回收後仍然存活的對象就會被放到老年代中。而且大對象直接進入老年代。

3、永久代:
即方法區。

參考博文:http://www.knowsky.com/889010.html

發佈了55 篇原創文章 · 獲贊 11 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章