Java GC Tutorials - Herong's Tutorial Examples - v1.11, by Dr. Herong Yang
Performance Jumps Not Related to GC
This section provides a tutorial showing that Performance jumps are not related garbage collections.
In the last tutorial, we learned that our test program GCPerformance.java has some strange performance jumps running on Windows systems. Those jumps reach as high as 2 times than normal performance with chunk size of 16 objects.
In this tutorial, let's run the test again with GC logging to see those jumps are resulted from garbage collections or not:
[0.029s][info][gc] Using G1 [0.046s][info][gc] Periodic GC disabled [0.319s][info][gc] GC(0) Pause Young (Concurrent Start) (G1 Humongous Allocation) 722M->80M(1600M) 5.998ms [0.319s][info][gc] GC(1) Concurrent Cycle [0.322s][info][gc] GC(1) Pause Remark 97M->97M(1600M) 1.007ms [0.323s][info][gc] GC(1) Pause Cleanup 97M->97M(1600M) 0.141ms [0.329s][info][gc] GC(1) Concurrent Cycle 10.294ms Parameters: Size=1024KB, Base=32, Chunk=16, Wait=0ms, Warmup=32 Real:Exec Lat. Throughput Total:Free Proc. Time:Time ms/o Ave:Min:Max:Chunk Mem.:Mem. Obj. 4:4 250 4000:4000:4000:4000 1638400:1145618 16 25:25 1314 1280:761:4000:761 1638400:1111824 32 30:30 1314 1600:761:4000:3200 1638400:1079056 48 35:35 1314 1828:761:4000:3200 1638400:1046288 64 40:40 1314 2000:761:4000:3200 1638400:1013520 80 44:44 1314 2181:761:4000:4000 1638400:980752 96 49:49 1314 2285:761:4000:3200 1638400:947984 112 54:54 1314 2370:761:4000:3200 1638400:915216 128 [0.425s][info][gc] GC(2) Pause Young (Concurrent Start) (G1 Humongous Allocation) 722M->80M(1600M) 2.773ms [0.425s][info][gc] GC(3) Concurrent Cycle [0.428s][info][gc] GC(3) Pause Remark 91M->91M(1600M) 1.154ms [0.429s][info][gc] GC(3) Pause Cleanup 93M->93M(1600M) 0.125ms 64:64 1314 2250:761:4000:1600 1638400:1538731 144 68:68 1314 2352:761:4000:4000 1638400:1505963 160 [0.435s][info][gc] GC(3) Concurrent Cycle 9.975ms 72:72 1314 2444:761:4000:4000 1638400:1473195 176 77:77 1314 2493:761:4000:3200 1638400:1440427 192 81:81 1314 2567:761:4000:4000 1638400:1407659 208 85:85 1314 2635:761:4000:4000 1638400:1374891 224 88:88 1314 2727:761:5333:5333 1638400:1342123 240 92:92 1314 2782:761:5333:4000 1638400:1309355 256 96:96 1314 2833:761:5333:4000 1638400:1276587 272 100:100 1314 2880:761:5333:4000 1638400:1243819 288 104:104 1314 2923:761:5333:4000 1638400:1211051 304 109:109 1314 2935:761:5333:3200 1638400:1178283 320 113:113 1314 2973:761:5333:4000 1638400:1145515 336 117:117 1314 3008:761:5333:4000 1638400:1112747 352 121:121 1314 3041:761:5333:4000 1638400:1079979 368 125:125 1314 3072:761:5333:4000 1638400:1047211 384 129:129 1314 3100:761:5333:4000 1638400:1013937 400 133:133 1314 3127:761:5333:4000 1638400:981169 416 137:137 1314 3153:761:5333:4000 1638400:948401 432 141:141 1314 3177:761:5333:4000 1638400:915633 448 [0.512s][info][gc] GC(4) Pause Young (Concurrent Start) (G1 Humongous Allocation) 721M->80M(1600M) 2.590ms [0.512s][info][gc] GC(5) Concurrent Cycle [0.515s][info][gc] GC(5) Pause Remark 91M->91M(1600M) 1.072ms [0.515s][info][gc] GC(5) Pause Cleanup 93M->93M(1600M) 0.137ms 150:150 1314 3093:761:5333:1777 1638400:1538714 464 [0.518s][info][gc] GC(5) Concurrent Cycle 5.758ms 155:155 1314 3096:761:5333:3200 1638400:1505946 480 159:159 1314 3119:761:5333:4000 1638400:1473178 496 163:163 1314 3141:761:5333:4000 1638400:1440410 512 167:167 1314 3161:761:5333:4000 1638400:1407642 528 171:171 1314 3181:761:5333:4000 1638400:1374874 544 175:175 1314 3200:761:5333:4000 1638400:1342106 560 178:178 1314 3235:761:5333:5333 1638400:1309338 576 182:182 1314 3252:761:5333:4000 1638400:1276570 592 186:186 1314 3268:761:5333:4000 1638400:1243802 608 189:189 1314 3301:761:5333:5333 1638400:1211034 624 ---- Throughput jumped here - | And no GC process was running 194:194 1314 3298:761:5333:3200 1638400:1178266 640 198:198 1314 3313:761:5333:4000 1638400:1145498 656 203:203 1314 3310:761:5333:3200 1638400:1112730 672 208:208 1314 3307:761:5333:3200 1638400:1079962 688 211:211 1314 3336:761:5333:5333 1638400:1047194 704 216:216 1314 3333:761:5333:3200 1638400:1014426 720 219:219 1314 3360:761:5333:5333 1638400:981658 736 224:224 1314 3357:761:5333:3200 1638400:948890 752 228:228 1314 3368:761:5333:4000 1638400:916122 768 [0.599s][info][gc] GC(6) Pause Young (Concurrent Start) (G1 Humongous Allocation) 721M->80M(1600M) 2.696ms [0.599s][info][gc] GC(7) Concurrent Cycle [0.601s][info][gc] GC(7) Pause Remark 91M->91M(1600M) 0.888ms [0.602s][info][gc] GC(7) Pause Cleanup 93M->93M(1600M) 0.135ms 237:237 1314 3308:761:5333:1777 1638400:1538702 784 [0.605s][info][gc] GC(7) Concurrent Cycle 5.848ms
As you can see from the output, the performance jumps happened between two GC processes. There was no interference from the garbage collector. So those performance jumps are not related to garbage collections.
I saw the same behavior with JDK 8 on an older computer too:
herong> \Progra~1\java\jdk1.8.0\bin\java -Xms1600m -Xmx1600m -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -XX:+PrintReferenceGC -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime GCPerformance 1024 32 16 0 64 Parameters: Size=1024KB, Base=32, Chunk=16, Wait=0ms, Warmup=64 ... Real:Exec Lat. Throughput Total:Free Proc. Time:Time ms/o Ave:Min:Max:Chunk Mem.:Mem. Obj. 31:31 1937 516:516:516:516 1126400:797556 16 62:62 1937 516:516:516:516 1126400:781171 32 93:93 1937 516:516:516:516 1126400:764787 48 124:124 1937 516:516:516:516 1126400:748403 64 156:156 2000 512:500:516:500 1126400:732019 80 187:187 2000 513:500:516:516 1126400:715634 96 218:218 2000 513:500:516:516 1126400:699250 112 249:249 2000 514:500:516:516 1126400:682866 128 Application time: 0.7555145 seconds {Heap before GC invocations=2 (full 0): def new generation total 819200K, used 447629K [... eden space 409600K, 99% used [... from space 409600K, 9% used [... to space 409600K, 0% used [... tenured generation total 307200K, used 0K [... the space 307200K, 0% used [... Metaspace used 1561K, capacity 2246K, committed 2368K, reserved 4480K [GC (Allocation Failure) [DefNew Desired survivor size 209715200 bytes, new threshold 15 (max 15) - age 1: 37751136 bytes, 37751136 total - age 3: 250144 bytes, 38001280 total : 447629K->37110K(819200K), 0.0117398 secs] 447629K->37110K(1126400K), 0.0117658 secs] Heap after GC invocations=3 (full 0): def new generation total 819200K, used 37110K [... eden space 409600K, 0% used [... from space 409600K, 9% used [... to space 409600K, 0% used [... tenured generation total 307200K, used 0K [... the space 307200K, 0% used [... Metaspace used 1561K, capacity 2246K, committed 2368K, reserved 4480K } Total time for which application threads were stopped: 0.0121600 seconds, ... 280:280 2000 514:500:516:516 1126400:1076055 144 312:312 2000 512:500:516:500 1126400:1059671 160 343:343 2000 513:500:516:516 1126400:1043286 176 374:374 2000 513:500:516:516 1126400:1026902 192 405:405 2000 513:500:516:516 1126400:1010518 208 436:436 2000 513:500:516:516 1126400:994134 224 468:468 2000 512:500:516:500 1126400:977749 240 499:499 2000 513:500:516:516 1126400:961365 256 530:530 2000 513:500:516:516 1126400:944981 272 561:561 2000 513:500:516:516 1126400:928597 288 592:592 2000 513:500:516:516 1126400:912212 304 624:624 2000 512:500:516:500 1126400:895828 320 655:655 2000 512:500:516:516 1126400:879444 336 686:686 2000 513:500:516:516 1126400:863060 352 717:717 2000 513:500:516:516 1126400:846675 368 748:748 2000 513:500:516:516 1126400:830291 384 780:780 2000 512:500:516:500 1126400:813907 400 811:811 2000 512:500:516:516 1126400:797523 416 826:826 2000 523:500:1066:1066 1126400:781138 432 ---- Throughput jumped on here - | 858:858 2000 522:500:1066:500 1126400:764754 448 889:889 2000 521:500:1066:516 1126400:748370 464 920:920 2000 521:500:1066:516 1126400:731986 480 951:951 2000 521:500:1066:516 1126400:715601 496 982:982 2000 521:500:1066:516 1126400:699217 512 1014:1014 2000 520:500:1066:500 1126400:682833 528 Application time: 0.7576008 seconds {Heap before GC invocations=3 (full 0): def new generation total 819200K, used 446638K [... eden space 409600K, 99% used [... from space 409600K, 9% used [... to space 409600K, 0% used [... tenured generation total 307200K, used 0K [... the space 307200K, 0% used [... Metaspace used 1561K, capacity 2246K, committed 2368K, reserved 4480K [GC (Allocation Failure) [DefNew Desired survivor size 209715200 bytes, new threshold 15 (max 15) - age 1: 36701584 bytes, 36701584 total - age 2: 936 bytes, 36702520 total - age 4: 250144 bytes, 36952664 total : 446638K->36086K(819200K), 0.0101967 secs] 446638K->36086K(1126400K), 0.0102218 secs] Heap after GC invocations=4 (full 0): def new generation total 819200K, used 36086K [... eden space 409600K, 0% used [... from space 409600K, 8% used [... to space 409600K, 0% used [... tenured generation total 307200K, used 0K [... the space 307200K, 0% used [... Metaspace used 1561K, capacity 2246K, committed 2368K, reserved 4480K } Total time for which application threads were stopped: 0.0106689 s ...
As you can see from the output, the first performance jump happened between two Minor GCs. During that period, the applications ran for 0.7576008 seconds, without any interference from the garbage collector.
So those performance jumps are not related to garbage collections.
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"
The Z Garbage Collector (ZGC) - "+XX:+UseZGC"
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 Object Size
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
GCPerfP99V2.java - Percentile Performance with Load
GCPerfP99V2.java - Work Load Level
GCPerfP99V2.java - Object Number and Size
Performance Tests on Serial Collector
Performance Tests on Parallel collector
Performance Tests on Concurrent collector
Performance Tests on G1 collector