一、基础知识
1. Sun JVM内存基本结构:
其中,比较重要的是Permanent Space(方法区),Java Object Heap(堆区)
Heap Space又可分为YoungGeneration(年轻代)和Old Generation(年老代)
而年轻代又可分为EdenSpace和Survivor Space
2. 对象可及性判断:
目前定义了几个root,也就是这几个对象是jvm虚拟机不会被回收的对象,所以这些对象引用的对象都是在使用中的对象,
这些对象未使用的对象就是即将要被回收的对象。简单就是说:如果对象能够达到root,就不会被回收,如果对象不能够达到root,就会被回收。
如下图:对象D访问不到根对象,所以就会被回收
以下对象会被认为是root对象:
被启动类(bootstrap加载器)加载的类和创建的对象
jvm运行时方法区类静态变量(static)引用的对象
jvm运行时方法去常量池引用的对象
jvm当前运行线程中的虚拟机栈变量表引用的对象
本地方法栈中(jni)引用的对象
由于这种算法即使存在互相引用的对象,但如果这两个对象无法访问到根对象,还是会被回收。如下图:对象C和对象D互相引用,但是由于无法访问根,所以会被回收。
jvm在确定是否回收的对象的时候采用的是root搜索算法来实现。
3. 不同代的垃圾回收算法
说明:对于FULL GC,本文中的定义是指GC日志中出现full gc字样的垃圾收集,或者serial old收集(当CMS并行收集出现Concurrent Mode Failure会退化为serial old)时的垃圾收集;
Dragoon监控中的full gc次数是指年老代的回收次数,即本文中的FULL GC和CMS收集;
Eden Space用于存放新生成的对象,经过一次垃圾回收后会进入Survivor Space;
Survivor Space分为均等的两块,每次垃圾回收会将有用的对象从一块移到另一块(停止复制算法/ minor GC),经过指定次数的回收后(由MaxTenuringThreshold参数确定,当指定-XX:+UseAdaptiveSizePolicy后,会取Survivor中超过一半对象的age和MaxTenuringThreshold的最小值);
Tenured Space则执行标记清扫回收算法(CMS收集策略,软引用对象不会回收),如果出现Concurrent Mode Failure,则进入full GC(软引用对象会被回收);
4. 不同代大小的分配参数
方法区分配参数: -XX:MaxPermSize
堆区分配参数: -Xms,-Xmx
年轻代分配参数: -XX:NewRatio 设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5
-Xmn:设置年轻代大小;
Eden与Survivor大小参数: -XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6
二、问题查找
5. Scout新机房生产环境启动参数示例:
参数含义:
-XX:MaxPermSize=256 方法区大小为256M
-Xms3071m –Xmx3071m 堆区大小为3071m
-Xmn1151m 堆区的年轻代大小为1151m
-DisableExplicitGC System.gc()无效
-XX:SurvivorRatio=6 两个survivor和一个Eden区的比值为2:6;
-XX:MaxTenuringThreshold=5 在survivor代复制5次后的对象进入年老代;
-XX:CMSInitiatingOccupancyFraction=70 年老代内存占用超过70%时进行垃圾回收
-XX:+UseConcMarksweepGC 使用并发收集器
-XX:+UseParNewGC设置年轻代为并行收集
-XX:+UseCMSCompactAtFullCollection FullGC时进行内存压缩(内存碎片整理)
-XX:+CMSFullGCsBeforeCompaction=5 执行5次FULL GC后对内存压缩 默认是0
-XX:+UseCMSInitiatingOccupancyOnly 指示只有在oldgeneration 在使用了初始化的比例后concurrent collector启动收集
Scout老机房生产环境启动参数示例:
老机房与新机房启动参数中最大的差别在于老机房未指定年轻代的大小;
6. GC日志解读:
(1):2013-08-26T22:02:03.472+0800: 29733.146: [GC 29733.146:[ParNew: 66342K->2586K(74560K), 0.0103010 secs]354578K->290937K(2242176K), 0.0105390 secs] [Times: user=0.02 sys=0.00,real=0.01 secs]
该日志表明这是一个年轻代的垃圾收集,其中年轻代总大小为74560K,经过垃圾收集后年轻代对象大小由66342K降为2586K; 堆区内存总大小为2242176K,经垃圾收集后,堆中对象大小由354578K降为290937K;
(2): 2013-08-26T22:03:30.155+0800: 29819.829: [GC [1CMS-initial-mark: 1562145K(2167616K)] 1574097K(2242176K), 0.0406330 secs][Times: user=0.04 sys=0.00, real=0.03 secs]
该日志表明这是年老代CMS垃圾收集(标记清理),其中年老代总大小为2167616K,其中由root直接可达的对象大小为 1562145K;
7. Scout生产环境日志:
1. Scout老机房GC日志:
2013-08-26T22:02:03.472+0800: 29733.146: [GC 29733.146: [ParNew:66342K->2586K(74560K), 0.0103010 secs] 354578K->290937K(2242176K),0.0105390 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
2013-08-26T22:02:07.509+0800: 29737.182: [GC 29737.182:[ParNew: 66522K->10624K(74560K), 0.1055890 secs]354873K->309226K(2242176K), 0.1059260 secs] [Times: user=0.23 sys=0.00,real=0.10 secs]
……300行
2013-08-26T22:03:29.520+0800:29819.194: [GC 29819.194: [ParNew: 74560K->10624K(74560K), 0.1820460 secs]1546399K->1527609K(2242176K), 0.1823400 secs] [Times: user=0.59 sys=0.05,real=0.18 secs]
2013-08-26T22:03:29.960+0800:29