在测试机上做压测,发现不同的机器上gc情况很不一致,多次压测排查后发现是JVM版本不一致导致的,
一个Openjdk,参数为
java version "1.6.0_22"
OpenJDK Runtime Environment (IcedTea6 1.10.6)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)
另一个OracleJdk,参数
java version "1.6.0_27"
Java(TM) SE Runtime Environment (build 1.6.0_27-b07)
Java HotSpot(TM) 64-Bit Server VM (build 20.2-b06, mixed mode),
测试机系统是rhel5-x86_64,硬件配置是一样的
gc参数:java -Xms6g -Xmx6g -Xmn1g -XX:PermSize=128m -XX:MaxPermSize=128m,用默认的垃圾回收策略
经过长时间的运行(24小时),Hotspot使用old区1.2g,而OpenJdk VM使用old区4.9g,导致oom。
(1)初步怀疑是默认的gc策略不同,知道OracleJdk默认的回收算法,鉴于OpenJdk是OracleJdk的开源版本,觉得也应该是一致的,但不确定,用java自带的工具,jinfo穷举,jinfo -flag UseParallelGC pid,输出-XX:+UseParallelGC
确定OracleJdk和Openjdk上默认的回收算法一致,都是UseParallelGC,且-XX:ParallelGCThreads=10。为了排除JDK以外的环境差异,在原本跑OpenJDK6b22的机器上装上用的Oracle JDK版本,oom消失。
(2)看了OpenJdk的官方介绍,两种jdk在版本接近时,性能也比较接近,且同样的情况下,OracleJdk的bug相对OpenJdk更少。猜想会不会正好在两个版本间,修复了某些bug,导致最终的性能有较大差距,遂上java官网,查找bug列表,结果没有找到按版本列出的bug列表。R大回复,HotSpot 20.x上确实有个bug会影响到GC行为,不过那个bug在官方的6u27上还没修,要到6u32才修。这个可能性也可以排除。
(3)写了个测试程序,在两个vm上执行,在不指定任何参数时,java -cp . GcTest,内存的消耗是接近的
OracleJdk:Memory: used 2051.8M free 35.0M total 2086.9M max 2668.5M
OpenJdk:Memory: used 2051.7M free 30.7M total 2082.4M max 2668.5M
指定参数后:java -Xmx200m -Xms200m -Xmn30m -XX:+PrintGCDetails -Xloggc:gc.log -cp . GcTest
消耗的内存仍然接近,java程序如下:
public class GcTest {
private static String megabyteString(long bytes) {
return String.format("%.1f", ((float) bytes) / 1024 / 1024);
}
private static void printUsedMemory() {
Runtime run = Runtime.getRuntime();
long free = run.freeMemory();
long total = run.totalMemory();
long max = run.maxMemory();
long used = total - free;
System.out.println("Memory: used " + megabyteString(used) + "M" + " free " + megabyteString(free) + "M" + " total "
+ megabyteString(total) + "M" + " max " + megabyteString(max) + "M");
}
public static void main(String[] args) {
GcTest test = new GcTest();
for(int i = 0; i < 5000; i++) {
test.allocateMem();
}
printUsedMemory();
}
public void allocateMem() {
byte[] used = new byte[50 * 1024 * 1024];
}
彻底懵了,请各位赐教。