一、堆內存
Java 中的堆是 JVM 所管理的最大的一塊內存空間,主要用於存放各類類的實例對象。
在 Java 中,堆被劃分紅兩個不一樣的區域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被劃分爲三個區域:Eden、From Survivor、To Survivor。
這樣劃分的目的是爲了使 JVM 可以更好的管理堆內存中的對象,包括內存的分配以及回收。
堆的內存模型大體爲:算法
從圖中能夠看出: 堆大小 = 新生代 + 老年代。其中,堆的大小能夠經過參數 –Xms、-Xmx 來指定。
默認的,新生代 ( Young ) 與老年代 ( Old ) 的比例的值爲 1:2 ( 該值能夠經過參數 –XX:NewRatio 來指定 ),即:新生代 ( Young ) = 1/3 的堆空間大小。老年代 ( Old ) = 2/3 的堆空間大小。其中,新生代 ( Young ) 被細分爲 Eden 和 兩個 Survivor 區域,這兩個 Survivor 區域分別被命名爲 from 和 to,以示區分。
默認的,Eden : from : to = 8 : 1 : 1 ( 能夠經過參數 –XX:SurvivorRatio 來設定 ),即: Eden = 8/10 的新生代空間大小,from = to = 1/10 的新生代空間大小。
JVM 每次只會使用 Eden 和其中的一塊 Survivor 區域來爲對象服務,因此不管何時,老是有一塊 Survivor 區域是空閒着的。所以,新生代實際可用的內存空間爲 9/10 ( 即90% )的新生代空間。spa
二、GC堆
Java 中的堆也是 GC 收集垃圾的主要區域。GC 分爲兩種:Minor GC、Full GC ( 或稱爲 Major GC )。
Minor GC 是發生在新生代中的垃圾收集動做,所採用的是複製算法。
新生代幾乎是全部 Java 對象出生的地方,即 Java 對象申請的內存以及存放都是在這個地方。Java 中的大部分對象一般不需長久存活,具備朝生夕滅的性質。當一個對象被斷定爲 「死亡」 的時候,GC 就有責任來回收掉這部分對象的內存空間。新生代是 GC 收集垃圾的頻繁區域。當對象在 Eden ( 包括一個 Survivor 區域,這裏假設是 from 區域 ) 出生後,在通過一次 Minor GC 後,若是對象還存活,而且可以被另一塊 Survivor 區域所容納( 上面已經假設爲 from 區域,這裏應爲 to 區域,即 to 區域有足夠的內存空間來存儲 Eden 和 from 區域中存活的對象 ),則使用複製算法將這些仍然還存活的對象複製到另一塊 Survivor 區域 ( 即 to 區域 ) 中,而後清理所使用過的 Eden 以及 Survivor 區域 ( 即 from 區域 ),而且將這些對象的年齡設置爲1,之後對象在 Survivor 區每熬過一次 Minor GC,就將對象的年齡 + 1,當對象的年齡達到某個值時 ( 默認是 15 歲,能夠經過參數 -XX:MaxTenuringThreshold 來設定 ),這些對象就會成爲老年代。但這也不是必定的,對於一些較大的對象 ( 即須要分配一塊較大的連續內存空間 ) 則是直接進入到老年代。Full GC 是發生在老年代的垃圾收集動做,所採用的是標記-清除算法。現實的生活中,老年代的人一般會比新生代的人 「早死」。堆內存中的老年代(Old)不一樣於個,老年代裏面的對象幾乎個個都是在 Survivor 區域中熬過來的,它們是不會那麼容易就 「死掉」 了的。所以,Full GC 發生的次數不會有 Minor GC 那麼頻繁,而且作一次 Full GC 要比進行一次 Minor GC 的時間更長。另外,標記-清除算法收集垃圾的時候會產生許多的內存碎片 ( 即不連續的內存空間 ),此後須要爲較大的對象分配內存空間時,若沒法找到足夠的連續的內存空間,就會提早觸發一次 GC 的收集動做。線程
三、GC日誌
設置 JVM 參數爲 -XX:+PrintGCDetails,使得控制檯可以顯示 GC 相關的日誌信息日誌
Full GC 信息與 Minor GC 的信息是類似的。從 Full GC 信息可知,新生代可用的內存大小約爲 18M,則新生代實際分配獲得的內存空間約爲 20M(爲何是 20M? 請繼續看下面…)。老年代分得的內存大小約爲 42M,堆的可用內存的大小約爲 60M。能夠計算出: 18432K ( 新生代可用空間 ) + 42112K ( 老年代空間 ) = 60544K ( 堆的可用空間 )新生代約佔堆大小的 1/3,老年代約佔堆大小的 2/3。也能夠看出,GC 對新生代的回收比較樂觀,而對老年代以及方法區的回收並不明顯或者說不及新生代。而且在這裏 Full GC 耗時是 Minor GC 的 22.89 倍。
四、JVM參數對象
配置參數 | 功能 |
-Xms | 初始堆大小。如:-Xms256m |
-Xmx | 最大堆大小。如:-Xms512m |
-Xmn | 新生代大小。一般爲 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 個 Survivor 空間。實際可用空間爲 = Eden + 1 個 Survivor,即 90% |
-Xss | JDK1.5+ 每一個線程堆棧大小爲 1M,通常來講若是棧不是很深的話, 1M 是絕對夠用了的 |
-XX:NewRatio | 新生代與老年代的比例。如-XX:NewRatio=2,則新生代佔堆的1/3,老年代佔2/3 |
-XX:SurvivorRatio | 新生代中 Eden 與 Survivor 的比值。默認值爲 8。即 Eden 佔新生代空間的 8/10,另外兩個 Survivor 各佔 1/10 |
-XX:+PrintGCDetails | 打印GC信息 |
-XX:+HeapDumpOnOutOfMemoryError | 讓虛擬機在發生內存溢出時 Dump 出當前的內存堆轉儲快照,以便分析用 |