1. Java堆中各代分布:
圖1:Java堆中各代分布 Young:主要是用來存放新生的對(duì)象,。 Old:主要存放應(yīng)用程序中生命周期長(zhǎng)的內(nèi)存對(duì)象,。 Permanent:是指內(nèi)存的永久保存區(qū)域,,主要存放Class和Meta的信息,Class在被 Load的時(shí)候被放入PermGen space區(qū)域. 它和和存放Instance的Heap區(qū)域不同,GC(Garbage Collection)不會(huì)在主程序運(yùn)行期對(duì)PermGen space進(jìn)行清理,,所以如果你的APP會(huì)LOAD很多CLASS的話,就很可能出現(xiàn)PermGen space錯(cuò)誤。
2. JVM 使用的GC算法是什么,? 分代收集,。 即將內(nèi)存分為幾個(gè)區(qū)域,將不同生命周期的對(duì)象放在不同區(qū)域里,; 在GC收集的時(shí)候,,頻繁收集生命周期短的區(qū)域(Young area); 比較少的收集生命周期比較長(zhǎng)的區(qū)域(Old area),; 基本不收集的永久區(qū)(Perm area),。
3. GC 和 Full GC 有什么區(qū)別? GC(或Minor GC):收集 生命周期短的區(qū)域(Young area),。 Full GC (或Major GC):收集生命周期短的區(qū)域(Young area)和生命周期比較長(zhǎng)的區(qū)域(Old area)對(duì)整個(gè)堆進(jìn)行垃圾收集。 他們的收集算法不同,,所以使用的時(shí)間也不同,。 GC 效率也會(huì)比較高,我們要盡量減少 Full GC 的次數(shù),。 當(dāng)顯示調(diào)用System.gc() 時(shí),,gc does a full collection(both young generation and tenured generation).
4. Minor GC后,Eden是空的嗎,? 是的,,Minor GC會(huì)把Eden中的所有活的對(duì)象都移到Survivor區(qū)域中,如果Survivor區(qū)中放不下,,那么剩下的活的對(duì)象就被移到Old generation 中,。
5. Garbage collection options(JDK1.4): 圖2:GC參數(shù)
堆設(shè)置
-Xms :初始堆大小 -Xmx :最大堆大小 -XX:NewSize=n :設(shè)置年輕代大小 -XX:NewRatio=n: 設(shè)置年輕代和年老代的比值。如:為3,,表示年輕代與年老代比值為1:3,,年輕代占整個(gè)年輕代年老代和的1/4 -XX:SurvivorRatio=n :年輕代中Eden區(qū)與兩個(gè)Survivor區(qū)的比值。注意Survivor區(qū)有兩個(gè),。如:3,,表示Eden:Survivor=3:2,一個(gè)Survivor區(qū)占整個(gè)年輕代的1/5 -XX:MaxPermSize=n :設(shè)置持久代大小 收集器設(shè)置 -XX:+UseSerialGC :設(shè)置串行收集器 -XX:+UseParallelGC :設(shè)置并行收集器 -XX:+UseParalledlOldGC :設(shè)置并行年老代收集器 -XX:+UseConcMarkSweepGC :設(shè)置并發(fā)收集器 垃圾回收統(tǒng)計(jì)信息 -XX:+PrintHeapAtGC GC的heap詳情 -XX:+PrintGCDetails GC詳情 -XX:+PrintGCTimeStamps 打印GC時(shí)間信息 -XX:+PrintTenuringDistribution 打印年齡信息等 -XX:+HandlePromotionFailure 老年代分配擔(dān)保(true or false)
并行收集器設(shè)置
-XX:ParallelGCThreads=n :設(shè)置并行收集器收集時(shí)使用的CPU數(shù),。并行收集線程數(shù),。 -XX:MaxGCPauseMillis=n :設(shè)置并行收集最大暫停時(shí)間 -XX:GCTimeRatio=n :設(shè)置垃圾回收時(shí)間占程序運(yùn)行時(shí)間的百分比。公式為1/(1+n) 并發(fā)收集器設(shè)置 -XX:+CMSIncrementalMode :設(shè)置為增量模式,。適用于單CPU情況,。 -XX:ParallelGCThreads=n :設(shè)置并發(fā)收集器年輕代收集方式為并行收集時(shí),,使用的CPU數(shù)。并行收集線程數(shù),。
6. 例子:Heap size 設(shè)置 場(chǎng)景:在JAVA_HOME下demo/jfc/SwingSet2/目錄下執(zhí)行下面的命令: java -jar -Xmn4m -Xms16m -Xmx16m SwingSet2.jar 系統(tǒng)輸出:
調(diào)優(yōu):將-Xms和-Xmx選項(xiàng)設(shè)置為32m,,而-Xmn為1/4的-Xmx值。 結(jié)果:執(zhí)行java -jar –Xmn8m –Xms32m -Xmx32m SwingSet2.jar,,系統(tǒng)正常運(yùn)行,。
7. JVM Runtime Data Area(運(yùn)行時(shí)數(shù)據(jù)區(qū)): 圖3:JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)(一) Heap: JVM只有一個(gè)為所有線程所共享的堆,所有的類實(shí)例和數(shù)組都是在堆中創(chuàng)建的,。 Method area: JVM只有一個(gè)為所有的線程所共享的方法區(qū),。它存儲(chǔ)類結(jié)構(gòu),例如運(yùn)行時(shí)常量池,,成員和方法數(shù)據(jù)以及方法,、構(gòu)造方法的代碼。 Java Stacks:每個(gè)JVM線程擁有一個(gè)私有的棧,。 Pc registers: JVM可以同時(shí)支持運(yùn)行多個(gè)線程,,因此每個(gè)線程需要各自的PC(program counter)寄存器。 Native method stacks: 保存native方法進(jìn)入?yún)^(qū)域的地址 ,。
圖4:JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)(二) Heap和Method area被所有線程共享,,其生存期和JVM的生存期相同;Java Stacks,、Pc registers,、Native method stacks被每個(gè)線程獨(dú)自擁有,其生存期和線程的生存期相同,。
8. 常見的內(nèi)存泄露錯(cuò)誤 很多開發(fā)人員都碰到過java.lang.OutOfMemoryError的錯(cuò)誤,。這種錯(cuò)誤又分兩種:java.lang.OutOfMemoryError: Java heap space和java.lang.OutOfMemoryError: PermGen space。引起這種錯(cuò)誤的原因可能是程序問題,,也可能是是JVM參數(shù)配置問題引起的,。若是參數(shù)問題,前者可以同過配置-Xms和-Xmx參數(shù)來設(shè)置,,而后者可以通過配置 -XX:PermSize和-XX:MaxPermSize來設(shè)置,。
9. 參考資料:
1. A brief history of garbage collection – http://www-128.ibm.com/developerworks/java/library/j-jtp10283/ 2. Garbage collection in the HotSpot JVM – http://www-128.ibm.com/developerworks/java/library/j-jtp11253/ 3. Tuning Garbage Collection with the 5.0 JavaTM Virtual Machine http://java./docs/hotspot/gc5.0/gc_tuning_5.html 4. Diagnosing a GC problem –
GC (minor )日志
Full GC 日志
-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:-HandlePromotionFailure -XX:+PrintHeapAtGC -XX:+PrintGCTimeStamps
-XX:+PrintGCDetails -XX:+PrintTenuringDistribution |
|