1 /* 2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * Results of running the JstatGcTool ("jstat -gccapacity <pid>") 26 * 27 * Output example: 28 * NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC YGC FGC 29 * 41984.0 671744.0 41984.0 5248.0 5248.0 31488.0 83968.0 1343488.0 83968.0 83968.0 512.0 110592.0 4480.0 0 0 30 31 * Output description: 32 * NGCMN Minimum new generation capacity (KB). 33 * NGCMX Maximum new generation capacity (KB). 34 * NGC Current new generation capacity (KB). 35 * S0C Current survivor space 0 capacity (KB). 36 * S1C Current survivor space 1 capacity (KB). 37 * EC Current eden space capacity (KB). 38 * OGCMN Minimum old generation capacity (KB). 39 * OGCMX Maximum old generation capacity (KB). 40 * OGC Current old generation capacity (KB). 41 * OC Current old space capacity (KB). 42 * MCMN Minimum metaspace capacity (KB). 43 * MCMX Maximum metaspace capacity (KB). 44 * MC Current metaspace capacity (KB). 45 * YGC Number of Young generation GC Events. 46 * FGC Number of Full GC Events. 47 */ 48 package utils; 49 50 import common.ToolResults; 51 import java.lang.management.GarbageCollectorMXBean; 52 import java.lang.management.ManagementFactory; 53 import java.util.Arrays; 54 import java.util.List; 55 56 public class JstatGcCapacityResults extends JstatResults { 57 58 public JstatGcCapacityResults(ToolResults rawResults) { 59 super(rawResults); 60 } 61 62 /** 63 * Checks the overall consistency of the results reported by the tool 64 */ 65 public void assertConsistency() { 66 67 // Check exit code 68 assertThat(getExitCode() == 0, "Unexpected exit code: " + getExitCode()); 69 70 // Check Young Gen consistency 71 float NGCMN = getFloatValue("NGCMN"); 72 float NGCMX = getFloatValue("NGCMX"); 73 assertThat(NGCMX >= NGCMN, "NGCMN > NGCMX (min generation capacity > max generation capacity)"); 74 75 float NGC = getFloatValue("NGC"); 76 assertThat(NGC >= NGCMN, "NGC < NGCMN (generation capacity < min generation capacity)"); 77 assertThat(NGC <= NGCMX, "NGC > NGCMX (generation capacity > max generation capacity)"); 78 79 float S0C = getFloatValue("S0C"); 80 assertThat(S0C <= NGC, "S0C > NGC (survivor space 0 capacity > new generation capacity)"); 81 82 float S1C = getFloatValue("S1C"); 83 assertThat(S1C <= NGC, "S1C > NGC (survivor space 1 capacity > new generation capacity)"); 84 85 float EC = getFloatValue("EC"); 86 assertThat(EC <= NGC, "EC > NGC (eden space capacity > new generation capacity)"); 87 88 // Verify relative size of NGC and S0C + S1C + EC. 89 // The rule depends on if the tenured GC is parallel or not. 90 // For parallell GC: NGC >= S0C + S1C + EC 91 // For non-parallell GC: NGC == S0C + S1C + EC 92 boolean isTenuredParallelGC = isTenuredParallelGC(); 93 String errMsg = String.format( 94 "NGC %s (S0C + S1C + EC) (NGC = %.1f, S0C = %.1f, S1C = %.1f, EC = %.1f, (S0C + S1C + EC) = %.1f)", 95 isTenuredParallelGC ? "<" : "!=", NGC, S0C, S1C, EC, S0C + S1C + EC); 96 if (isTenuredParallelGC) { 97 assertThat(NGC >= S0C + S1C + EC, errMsg); 98 } else { 99 assertThat(checkFloatIsSum(NGC, S0C, S1C, EC), errMsg); 100 } 101 102 // Check Old Gen consistency 103 float OGCMN = getFloatValue("OGCMN"); 104 float OGCMX = getFloatValue("OGCMX"); 105 assertThat(OGCMX >= OGCMN, "OGCMN > OGCMX (min generation capacity > max generation capacity)"); 106 107 float OGC = getFloatValue("OGC"); 108 assertThat(OGC >= OGCMN, "OGC < OGCMN (generation capacity < min generation capacity)"); 109 assertThat(OGC <= OGCMX, "OGC > OGCMX (generation capacity > max generation capacity)"); 110 float OC = getFloatValue("OC"); 111 assertThat(OC == OGC, "OC != OGC (old generation capacity != old space capacity (these values should be equal since old space is made up only from one old generation))"); 112 113 // Check Metaspace consistency 114 float MCMN = getFloatValue("MCMN"); 115 float MCMX = getFloatValue("MCMX"); 116 assertThat(MCMX >= MCMN, "MCMN > MCMX (min generation capacity > max generation capacity)"); 117 float MC = getFloatValue("MC"); 118 assertThat(MC >= MCMN, "MC < MCMN (generation capacity < min generation capacity)"); 119 assertThat(MC <= MCMX, "MGC > MCMX (generation capacity > max generation capacity)"); 120 121 122 } 123 124 /** 125 * Check if the tenured generation are currently using a parallel GC. 126 */ 127 protected static boolean isTenuredParallelGC() { 128 // Currently the only parallel GC for the tenured generation is PS MarkSweep. 129 List<String> parallelGCs = Arrays.asList(new String[] { "PS MarkSweep"}); 130 try { 131 List<GarbageCollectorMXBean> beans = ManagementFactory.getGarbageCollectorMXBeans(); 132 for (GarbageCollectorMXBean bean : beans) { 133 if (parallelGCs.contains(bean.getName())) { 134 return true; 135 } 136 } 137 } catch (Exception e) { 138 e.printStackTrace(); 139 } 140 return false; 141 } 142 143 private static final float FLOAT_COMPARISON_TOLERANCE = 0.0011f; 144 145 private static boolean checkFloatIsSum(float sum, float... floats) { 146 for (float f : floats) { 147 sum -= f; 148 } 149 150 return Math.abs(sum) <= FLOAT_COMPARISON_TOLERANCE; 151 } 152 153 private void assertThat(boolean b, String message) { 154 if (!b) { 155 throw new RuntimeException(message); 156 } 157 } 158 159 }