JVM簡介堆中新生代老年代淺析

1、JVM內存結構由程序計數器、堆、棧、本地方法棧、方法區等部分組成。
1)程序計數器
幾乎不佔有內存。用於取下一條執行的指令。
2)堆
全部經過new建立的對象的內存都在堆中分配,其大小能夠經過-Xmx和-Xms來控制。堆被劃分爲新生代和舊生代,新生代又被進一步劃分爲Eden和Survivor區,最後Survivor由FromSpace和ToSpace組成。
通常狀況將新生代分爲Eden ,兩塊Survivor區域;
新生代。新建的對象都是用新生代分配內存,Eden空間不足的時候,會把存活的對象轉移到Survivor中,新生代大小能夠由-Xmn來控制,也能夠用-XX:SurvivorRatio來控制Eden和Survivor的比例舊生代。用於存放新生代中通過屢次垃圾回收仍然存活的對象。
3)棧
每一個線程執行每一個方法的時候都會在棧中申請一個棧幀,每一個棧幀包括局部變量區和操做數棧,用於存放這次方法調用過程當中的臨時變量、參數和中間結果。
4)本地方法棧
用於支持native方法的執行,存儲了每一個native方法調用的狀態。
5)方法區
存放了要加載的類信息、靜態變量、final類型的常量、屬性和方法信息。JVM用永久代(PermanetGeneration)來存放方法區,(在JDK的HotSpot虛擬機中,能夠認爲方法區就是永久代,可是在其餘類型的虛擬機中,沒有永久代的概念,有關信息能夠看周志明的書)可經過-XX:PermSize和-XX:MaxPermSize來指定最小值和最大值。java

2、JVM垃圾回收機制
JVM分別對新生代和舊生代採用不一樣的垃圾回收機制
新生代的GC:
新生代一般存活時間較短,所以基於複製算法來進行回收,所謂複製算法就是掃描出存活的對象,並複製到一塊新的徹底未使用的空間中,對應於新生代,就是在Eden和其中一個Survivor,複製到另外一個之間Survivor空間中,而後清理掉原來就是在Eden和其中一個Survivor中的對象。新生代採用空閒指針的方式來控制GC觸發,指針保持最後一個分配的對象在新生代區間的位置,當有新的對象要分配內存時,用於檢查空間是否足夠,不夠就觸發GC。當連續分配對象時,對象會逐漸從eden到 survivor,最後到老年代。算法

用javavisualVM來查看,能明顯觀察到新生代滿了後,會把對象轉移到舊生代,而後清空繼續裝載,當舊生代也滿了後,就會報outofmemory的異常。spa

舊生代與新生代不一樣,對象存活的時間比較長,比較穩定,所以採用標記(Mark)算法來進行回收,所謂標記就是掃描出存活的對象,而後再進行回收未被標記的對象,回收後對用空出的空間要麼進行合併,要麼標記出來便於下次進行分配,總之就是要減小內存碎片帶來的效率損耗。線程

3、GC堆指針

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,以示區分。
默認的,Edem : from : to = 8 :1 : 1 ( 能夠經過參數–XX:SurvivorRatio 來設定 ),即: Eden = 8/10 的
新生代空間大小,from = to = 1/10 的新生代空間大小。
JVM 每次只會使用 Eden 和其中的一塊 Survivor 區域來爲對象服務,因此不管何時,老是有一塊Survivor區域是空閒着的。
所以,新生代實際可用的內存空間爲 9/10 ( 即90% )的新生代空間。blog

4、JVM 參數選項
下面只列舉其中的幾個經常使用和容易掌握的配置選項:
-Xms
初始堆大小。如:-Xms256m內存

-Xmx
最大堆大小。如:-Xmx512m虛擬機

-Xmn
新生代大小。一般爲 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 個 Survivor 空間。實際可用空間爲 = Eden + 1 個 Survivor,即 90% io

-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:PermSize
永久代(方法區)的初始大小

-XX:MaxPermSize
永久代(方法區)的最大值

-XX:+PrintGCDetails
打印 GC 信息

-XX:+HeapDumpOnOutOfMemoryError讓虛擬機在發生內存溢出時 Dump 出當前的內存堆轉儲快照,以便分析用

相關文章
相關標籤/搜索