內存模型(HotSpot)

- 堆用來主要存放種類實例對象。
- 堆主要分爲新生代(Young)與老年代(Old)。
- 新生代包含:Eden,From Survivor,To Survivor。
- 老年代主要用來保存程序聲明週期長的對象。
- 永生代(Permanent):方法區,不屬於java堆,另外一個名字Non-Heap,指永久保存的區域,主要存放Class和Meta信息。
方法區回收
方法區回收的性價比比較低。在堆中,GC一次能夠回收70%-95%空間,而永生代只能回收不多的空間。但也會執行回收,當內存嚴重不足時,會回收方法區的無用的常量和無用的類。java
GC
MinorGC
- MinorGC發生在新生代,採用複製算法。
- Eden(包含一個survivor區域)對象初始化------>MinorGC------>若是在另外一個Survivor有足夠空間容納對象,則經過複製算法把對象複製到Survivor並標記年齡爲1------>清理Eden區域------>後續每次MinorGC,年齡都+1---->當到達閾值(default 15)這些對象就會晉升成爲老年代。
- 若是是大對象,可能直接進入老年代。
FullGC(stop the world)
- FullGC發生在老年代,採用標記-消除或者標記-整理算法。
- 發生MinorGC前,先檢查Old最大的可用連續空間>新生代全部對象之和,若是成立,則MinorGC安全,反之,會檢查HandlePromotionFailure是否容許擔保失敗,如果,則檢查Old最大可用連續空間>歷次晉升到Old的對象的平均大小,若是成立,則嘗試MinorGC.若是不容許擔保失敗,則轉換爲一次FullGC。
- 標記-清除算法和標記-整理算法會產生不少內存碎片,若是後續要分配一個大對象,沒有足夠多可用的連續空間,就會提早FullGC。
GC日誌
添加vm參數:-XX:+PrintGCDetails
算法
MinorGC
[GC [PSYoungGen: 1019K->568K(28672K)] 1019K->568K(92672K), 0.0529244 secs] [Times: user=0.00 sys=0.00, real=0.06 secs]
翻譯: [GC [PSYoungGen{新生代} 1019K{MinorGC前新生代內存使用}->568K{MinorGC後新生代內存使用}(28672K{新生代總的內存大小}) 1019K{MinorGC前JVM堆內存使用的大小}->568K{MinorGC後JVM堆內存使用的大小}(92672K{堆的可用內存大小}), 0.0529244 secs{MinorGC總耗時}] [Times: user{用戶耗時}=0.00 sys{系統耗時}=0.00, real{實際耗時}=0.06 secs]安全
FullGC
[Full GC [PSYoungGen: 568K->0K(28672K)] [ParOldGen: 0K->478K(64000K)] 568K->478K(92672K) [PSPermGen: 2484K->2483K(21504K)], 0.0178331 secs] [Times: user=0.01 sys=0.00, real=0.02 secs]
翻譯: [Full GC [PSYoungGen: 568K->0K(28672K)] [ParOldGen{老年代}: 0K{FullGC前老年代內存使用}->478K{FullGC後老年代內存使用}(64000K{老年代總的內存大小})] 568K{FullGC前JVM堆內存使用的大小}->478K{FullGC後JVM堆內存使用的大小}(92672K{堆的可用內存大小}) [PSPermGen{永久代}: 2484K->2483K(21504K)], 0.0178331 secs] [Times: user=0.01 sys=0.00, real=0.02 secs]併發
JVM參數
-XX:+<option> 啓用選項
-XX:-<option>不啓用選項
-XX:<option>=<number>
-XX:<option>=<string>
jvm
堆設置
- -Xms :初始堆大小
- -Xmx :最大堆大小
- -Xmn:新生代大小。一般爲 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 個 Survivor 空間。實際可用空間爲 = Eden + 1 個 Survivor,即 90%
- -XX:NewSize=n :設置年輕代大小
- -XX:NewRatio=n: 設置年輕代和年老代的比值。如:爲3,表示年輕代與年老代比值爲1:3,年輕代佔整個年輕代年老代和的1/4
- -XX:SurvivorRatio=n :年輕代中Eden區與兩個Survivor區的比值。注意Survivor區有兩個。如:3,表示Eden:Survivor=3:2,一個Survivor區佔整個年輕代的1/5
- -XX:PermSize=n 永久代(方法區)的初始大小
- -XX:MaxPermSize=n :設置永久代大小
- -Xss 設定棧容量;對於HotSpot來講,雖然-Xoss參數(設置本地方法棧大小)存在,但其實是無效的,由於在HotSpot中並不區分虛擬機和本地方法棧。
- -XX:PretenureSizeThreshold (該設置只對Serial和ParNew收集器生效) 能夠設置進入老生代的大小限制
- -XX:MaxTenuringThreshold=1(默認15)垃圾最大年齡 若是設置爲0的話,則年輕代對象不通過Survivor區,直接進入年老代. 對於年老代比較多的應用,能夠提升效率.若是將此值設置爲一個較大值,則年輕代對象會在Survivor區進行屢次複製,這樣能夠增長對象再年輕代的存活 時間,增長在年輕代即被回收的機率 該參數只有在串行GC時纔有效.
收集器設置
- -XX:+UseSerialGC :設置串行收集器
- -XX:+UseParallelGC :設置並行收集器
- -XX:+UseParallelOldGC :設置並行年老代收集器
- -XX:+UseConcMarkSweepGC :設置併發收集器
垃圾回收統計信息
- -XX:+PrintHeapAtGC GC的heap詳情
- -XX:+PrintGCDetails GC詳情
- -XX:+PrintGCTimeStamps 打印GC時間信息
- -XX:+PrintTenuringDistribution 打印年齡信息等
- -XX:+HandlePromotionFailure 老年代分配擔保(true or false)
- -Xloggc:gc.log 指定日誌的位置
並行收集器設置
- -XX:ParallelGCThreads=n :設置並行收集器收集時使用的CPU數。並行收集線程數。
- -XX:MaxGCPauseMillis=n :設置並行收集最大暫停時間
- -XX:GCTimeRatio=n :設置垃圾回收時間佔程序運行時間的百分比。公式爲1/(1+n)
併發收集器設置
- -XX:+CMSIncrementalMode :設置爲增量模式。適用於單CPU狀況。
- -XX:ParallelGCThreads=n :設置併發收集器年輕代收集方式爲並行收集時,使用的CPU數。並行收集線程數。
其餘
- -XX:PermSize=10M和-XX:MaxPermSize=10M限制方法區大小。
- -XX:MaxDirectMemorySize=10M指定DirectMemory(直接內存)容量,若是不指定,則默認與JAVA堆最大值(-Xmx指定)同樣。
- -XX:+HeapDumpOnOutOfMemoryError 可讓虛擬機在出現內存溢出異常時Dump出當前的內存堆轉儲快照(.hprof文件)以便時候進行分析(好比Eclipse Memory Analysis)。
參考:http://www.javashuo.com/article/p-hdswzcrr-kg.html.net