Java 8 GC Tutorials - Herong's Tutorial Examples - v1.03, by Dr. Herong Yang
GCPerformance.java - GC Performance Test Program
This section describes a GC performance test program - GCPerformance.java.
In previous tutorials of the book, we learned how different garbage collectors work. Now in order to learn how to tune garbage collectors to improve application performance, I wrote the following test program:
/* GCPerformance.java * Copyright (c) HerongYang.com. All Rights Reserved. */ class GCPerformance { static MyList objList = null; static int objSize = 1024; // in KB, default = 1 MB static int baseSize = 32; // # of objects in the base static int chunkSize = 32; // # of objects in chunk static int wait = 1000; // in milliseconds: 1 second static int warmup = 256; // warmup loops: 256*32 = 8GB public static void main(String[] arg) { if (arg.length>0) objSize = Integer.parseInt(arg[0]); if (arg.length>1) baseSize = Integer.parseInt(arg[1]); if (arg.length>2) chunkSize = Integer.parseInt(arg[2]); if (arg.length>3) wait = Integer.parseInt(arg[3]); if (arg.length>4) warmup = Integer.parseInt(arg[4]); System.out.println("Parameters: "+"Size="+objSize+"KB" +", Base="+baseSize +", Chunk="+chunkSize +", Wait="+wait+"ms" +", Warmup="+warmup); objList = new MyList(); myTest(); } public static void myTest() { for (int m=0; m<baseSize; m++) { objList.add(new MyObject()); } for (int k=0; k<warmup; k++) { for (int m=0; m<chunkSize; m++) { objList.add(new MyObject()); } for (int m=0; m<chunkSize; m++) { objList.removeTail(); } } Runtime rt = Runtime.getRuntime(); System.out.println("Real:Exec Lat. Throughput " +"Total:Free Proc."); System.out.println("Time:Time ms/o Ave:Min:Max:Chunk " +" Mem.:Mem. Obj."); long dt0 = System.currentTimeMillis(); long dt1 = System.currentTimeMillis(); long minPerf = 999999; long maxPerf = 0; long count = 0; while (true) { for (int m=0; m<chunkSize; m++) { objList.add(new MyObject()); } for (int m=0; m<chunkSize; m++) { objList.removeTail(); } count++; mySleep(wait); long tm = rt.totalMemory()/1024; long fm = rt.freeMemory()/1024; long dt2 = System.currentTimeMillis(); long dt = dt2 - dt0; long de = dt - (count*wait); long perf = (1000*chunkSize)/(dt2-dt1-wait); // per second if (perf<minPerf) minPerf = perf; if (perf>maxPerf) maxPerf = perf; System.out.println((dt) // Real time in millis +":"+(de) // Execution time in millis +" "+(1000000/minPerf) // Latency (ms/1000 objects) +" "+((1000*count*chunkSize)/de) // Average throughput +":"+minPerf // Best throughput +":"+maxPerf // Worst throughput +":"+perf // Chunk throughput +" "+tm+":"+fm // Total and free memory in KB +" "+(count*chunkSize)); // Objects processed dt1 = dt2; } } static void mySleep(int t) { try { Thread.sleep(t); } catch (InterruptedException e) { System.out.println("Interreupted..."); } }
static class MyObject { private long[] obj = null; public MyObject next = null; public MyObject prev = null; public MyObject() { obj = new long[objSize*128]; // 128*8=1024 bytes for (int i=0; i<objSize*128; i++) { obj[i] = i/2+i/3+i/4+i/5; // some work load } } } static class MyList { MyObject head = null; MyObject tail = null; void add(MyObject o) { if (head==null) { head = o; tail = o; } else { o.prev = head; head.next = o; head = o; } } void removeTail() { if (tail!=null) { if (tail.next==null) { tail = null; head = null; } else { tail = tail.next; tail.prev = null; } } } } }
Some notes on the test program:
The output of the test program focuses on two performance metrics:
Throughput - Defined as "the number of objects processed per second". This is calculated as:
Latency - Defined as "the maximum time required to process a single object". This is calculated as:
Table of Contents
Heap Memory Area and Size Control
JVM Garbage Collection Logging
Introduction of Garbage Collectors
Serial Collector - "+XX:+UseSerialGC"
Parallel Collector - "+XX:+UseParallelGC"
Concurrent Mark-Sweep (CMS) Collector - "+XX:+UseConcMarkSweepGC"
Garbage First (G1) Collector - "+XX:+UseG1GC"
Object References and Garbage Collection
►Garbage Collection Performance Test Program
►GCPerformance.java - GC Performance Test Program
GCPerformance.java - Program Output
Performance Impact of Wait Time
Performance Impact of Chunk Size
Performance Jumps Not Related to GC
Performance Test and System Interruptions
"START /REALTIME" - Run JVM with Highest Priority
GCPerfP99.java - 99th Percentile Performance
GCPerfP99.java - Output Verification
Performance Tests on Serial Collector
Performance Tests on Parallel collector
Performance Tests on Concurrent collector
Performance Tests on G1 collector