在大型的java运用中,要进行程序调优,指定一个合适的垃圾回收机制是必不可少的,那如何可确定某gc是否使得程序最优化呢?我们可以查看jvm打印出 的gc日志来分析,并做出进一步优化,而目前并没有一篇文章明确的指明java中各种gc算法打印出日志的格式,以及如何阅读。所以接下来本文将试着边介 绍各种垃圾回收机制边解释该回收机制下log的格式。
1,垃圾收集算法
1.1 引用计数法(Reference Counting Collector)
系统记 录对象被应用的次数,当应用次数为0时,就可以将该对象所占内存回收。该算法可以不用暂停运用,但缺点是无法解决重复运用的问题。所以java并没有提供 此类垃圾回收器。
1.2 tracing算法(Tracing Collector)
tracing算法的垃圾收集器从根集开始扫描,识别出哪些对象可达,哪 些对象不可达,并用某种方式标记可达对象。
1.2.1 复制 ( Copying )算法
复制算法将堆等分成2个区域,一个区域含有现在的数据对象(ToSpace),而另一个区域包含废 弃的数据(FromSpace)。复制算法将存活的对象从FromSpace复制到ToSpace,然后切换Fromspace和ToSpace的指针, 以前的FromSpace变为现在的ToSpace区域。
1.2.2 标记-整理( Mark-Compact )算法
1.2.3 标记-清除(Mark-Sweep)
Using the -XX flags for our collectors for jdk6,
SerailGC
1,Serial Young GC
0.246: [GC 0.246: [DefNew: 1403K->105K(1984K), 0.0109275 secs] 1403K->1277K(6080K), 0.0110143 secs]
2, Serial Olg Gc
1.133: [GC 1.133: [DefNew: 960K->64K(960K), 0.0012208 secs]1.135: [Tenured: 7334K->7142K(7424K), 0.0213756 secs] 7884K->7142K(8384K), [Perm : 364K->364K(12288K)], 0.0226997 secs] [Times: user=0.01 sys=0.00, real=0.02 secs]
Parrallel GC serailGC的适应muti Core的加强版,就是在minorGC时候采用并行的进行收集,而fullGC并没有改变
CMS将老生代的回收分为4个阶段 其中只有2个阶段是要stop-the-world的,而其余阶段是不需要的,因此降低了系统暂停时间,缺点是在其余的2个阶段会更应用抢jvm资源。
从上图可以看出,CMS的运 行过程。
Concurrent Mark-Sweep GC log format:
Full GC 被调用的出现情况
promotion failed( mark-sweep-compact stop-the-world ) ParNew (promotion failed): 当老生代空闲空间存在碎片,导致没有足够大的连续空间开存放新生代对象的升级时,机会触发promotion failed。 此时调用一个Mark-Compact 垃圾收集器是很有必要的。(默认采用 Serial Old GC)
full promotion guarantee failure ( concurrent mode failure ): 当垃圾回收算法预测在下一次Conc-Mark-Sweep算法调用之前,老生代的空余空间将会被系统占用光。为了解决这一问题,垃 圾回收算法进入conccurent mode failure状态,调用一个 stop-the-world(serail Old GC)来清理系统Heap。
eg:为了触发这种情况 我们先分配64m内存给jvm,然后新生代和老年代的占用比例为7,即老年代用了7*8=58 触 发concurrent mode failure的情况:
public class FullPromotionGuaranteeFailure
{
public static void main(String[] args)
{
List<byte[]> bytesList = new ArrayList<byte[]>();
for (int i = 0; i < 7 * 8 * 1024; i++)
{
bytesList.add(new byte[1024]);
}
//bytesList = null; 没有必要的 gc会知道函数里面变量是否还会被引用
byte[] bytes = new byte[16 * 1024 * 1024];
String.valueOf(bytes[0]);
}
}
运 行时JVM参数:
-Xmx64m -Xms64m -XX:NewRatio=7 -XX:MaxTenuringThreshold=0 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+UseConcMarkSweepGC
-Xloggc:full-promotion-guarantee-failure.log
full-promotion-guarantee-failure.log 内容
调用Serial Old GC 是费时并且暂停了整个应用,这显然不是我们想看到的。为了 避 免办法出现( concurrent mode failure )这种情况,可以参考bluedavy的该篇blog GC 策略的调优
Stop-the-world GC happens when a JNI critical section is released . Here again the young generation collection failed due to "full promotion guarantee failure" and then the Full GC was invoked.