1 /* 2 * Copyright (c) 2003, 2018, 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 package sun.jvm.hotspot.tools; 26 27 import java.util.*; 28 import sun.jvm.hotspot.gc.epsilon.*; 29 import sun.jvm.hotspot.gc.g1.*; 30 import sun.jvm.hotspot.gc.parallel.*; 31 import sun.jvm.hotspot.gc.serial.*; 32 import sun.jvm.hotspot.gc.shared.*; 33 import sun.jvm.hotspot.debugger.JVMDebugger; 34 import sun.jvm.hotspot.memory.*; 35 import sun.jvm.hotspot.oops.*; 36 import sun.jvm.hotspot.runtime.*; 37 38 public class HeapSummary extends Tool { 39 40 public HeapSummary() { 41 super(); 42 } 43 44 public HeapSummary(JVMDebugger d) { 45 super(d); 46 } 47 48 public static void main(String[] args) { 49 HeapSummary hs = new HeapSummary(); 50 hs.execute(args); 51 } 52 53 @Override 54 public String getName() { 55 return "heapSummary"; 56 } 57 58 public void run() { 59 CollectedHeap heap = VM.getVM().getUniverse().heap(); 60 VM.Flag[] flags = VM.getVM().getCommandLineFlags(); 61 Map flagMap = new HashMap(); 62 if (flags == null) { 63 System.out.println("WARNING: command line flags are not available"); 64 } else { 65 for (int f = 0; f < flags.length; f++) { 66 flagMap.put(flags[f].getName(), flags[f]); 67 } 68 } 69 70 System.out.println(); 71 printGCAlgorithm(flagMap); 72 System.out.println(); 73 System.out.println("Heap Configuration:"); 74 printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap)); 75 printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap)); 76 printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap)); 77 printValMB("NewSize = ", getFlagValue("NewSize", flagMap)); 78 printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap)); 79 printValMB("OldSize = ", getFlagValue("OldSize", flagMap)); 80 printValue("NewRatio = ", getFlagValue("NewRatio", flagMap)); 81 printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap)); 82 printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap)); 83 printValMB("CompressedClassSpaceSize = ", getFlagValue("CompressedClassSpaceSize", flagMap)); 84 printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap)); 85 printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes()); 86 87 System.out.println(); 88 System.out.println("Heap Usage:"); 89 90 if (heap instanceof GenCollectedHeap) { 91 GenCollectedHeap genHeap = (GenCollectedHeap) heap; 92 for (int n = 0; n < genHeap.nGens(); n++) { 93 Generation gen = genHeap.getGen(n); 94 if (gen instanceof DefNewGeneration) { 95 System.out.println("New Generation (Eden + 1 Survivor Space):"); 96 printGen(gen); 97 98 ContiguousSpace eden = ((DefNewGeneration)gen).eden(); 99 System.out.println("Eden Space:"); 100 printSpace(eden); 101 102 ContiguousSpace from = ((DefNewGeneration)gen).from(); 103 System.out.println("From Space:"); 104 printSpace(from); 105 106 ContiguousSpace to = ((DefNewGeneration)gen).to(); 107 System.out.println("To Space:"); 108 printSpace(to); 109 } else { 110 System.out.println(gen.name() + ":"); 111 printGen(gen); 112 } 113 } 114 } else if (heap instanceof G1CollectedHeap) { 115 printG1HeapSummary((G1CollectedHeap)heap); 116 } else if (heap instanceof ParallelScavengeHeap) { 117 ParallelScavengeHeap psh = (ParallelScavengeHeap) heap; 118 PSYoungGen youngGen = psh.youngGen(); 119 printPSYoungGen(youngGen); 120 121 PSOldGen oldGen = psh.oldGen(); 122 long oldFree = oldGen.capacity() - oldGen.used(); 123 System.out.println("PS Old Generation"); 124 printValMB("capacity = ", oldGen.capacity()); 125 printValMB("used = ", oldGen.used()); 126 printValMB("free = ", oldFree); 127 System.out.println(alignment + (double)oldGen.used() * 100.0 / oldGen.capacity() + "% used"); 128 } else if (heap instanceof EpsilonHeap) { 129 EpsilonHeap eh = (EpsilonHeap) heap; 130 printSpace(eh.space()); 131 } else { 132 throw new RuntimeException("unknown CollectedHeap type : " + heap.getClass()); 133 } 134 135 System.out.println(); 136 printInternStringStatistics(); 137 } 138 139 // Helper methods 140 141 private void printGCAlgorithm(Map flagMap) { 142 long l = getFlagValue("UseTLAB", flagMap); 143 if (l == 1L) { 144 System.out.println("using thread-local object allocation."); 145 } 146 147 l = getFlagValue("UseConcMarkSweepGC", flagMap); 148 if (l == 1L) { 149 System.out.println("Concurrent Mark-Sweep GC"); 150 return; 151 } 152 153 l = getFlagValue("UseParallelGC", flagMap); 154 if (l == 1L) { 155 System.out.print("Parallel GC "); 156 l = getFlagValue("ParallelGCThreads", flagMap); 157 System.out.println("with " + l + " thread(s)"); 158 return; 159 } 160 161 l = getFlagValue("UseG1GC", flagMap); 162 if (l == 1L) { 163 System.out.print("Garbage-First (G1) GC "); 164 l = getFlagValue("ParallelGCThreads", flagMap); 165 System.out.println("with " + l + " thread(s)"); 166 return; 167 } 168 169 l = getFlagValue("UseEpsilonGC", flagMap); 170 if (l == 1L) { 171 System.out.println("Epsilon (no-op) GC"); 172 return; 173 } 174 175 System.out.println("Mark Sweep Compact GC"); 176 } 177 178 private void printPSYoungGen(PSYoungGen youngGen) { 179 System.out.println("PS Young Generation"); 180 MutableSpace eden = youngGen.edenSpace(); 181 System.out.println("Eden Space:"); 182 printMutableSpace(eden); 183 MutableSpace from = youngGen.fromSpace(); 184 System.out.println("From Space:"); 185 printMutableSpace(from); 186 MutableSpace to = youngGen.toSpace(); 187 System.out.println("To Space:"); 188 printMutableSpace(to); 189 } 190 191 private void printMutableSpace(MutableSpace space) { 192 printValMB("capacity = ", space.capacity()); 193 printValMB("used = ", space.used()); 194 long free = space.capacity() - space.used(); 195 printValMB("free = ", free); 196 System.out.println(alignment + (double)space.used() * 100.0 / space.capacity() + "% used"); 197 } 198 199 private static String alignment = " "; 200 201 private void printGen(Generation gen) { 202 printValMB("capacity = ", gen.capacity()); 203 printValMB("used = ", gen.used()); 204 printValMB("free = ", gen.free()); 205 System.out.println(alignment + (double)gen.used() * 100.0 / gen.capacity() + "% used"); 206 } 207 208 private void printSpace(ContiguousSpace space) { 209 printValMB("capacity = ", space.capacity()); 210 printValMB("used = ", space.used()); 211 printValMB("free = ", space.free()); 212 System.out.println(alignment + (double)space.used() * 100.0 / space.capacity() + "% used"); 213 } 214 215 public void printG1HeapSummary(G1CollectedHeap g1h) { 216 G1MonitoringSupport g1mm = g1h.g1mm(); 217 long edenRegionNum = g1mm.edenRegionNum(); 218 long survivorRegionNum = g1mm.survivorRegionNum(); 219 HeapRegionSetBase oldSet = g1h.oldSet(); 220 HeapRegionSetBase humongousSet = g1h.humongousSet(); 221 long oldRegionNum = oldSet.length() + humongousSet.length(); 222 printG1Space("G1 Heap:", g1h.n_regions(), 223 g1h.used(), g1h.capacity()); 224 System.out.println("G1 Young Generation:"); 225 printG1Space("Eden Space:", edenRegionNum, 226 g1mm.edenUsed(), g1mm.edenCommitted()); 227 printG1Space("Survivor Space:", survivorRegionNum, 228 g1mm.survivorUsed(), g1mm.survivorCommitted()); 229 printG1Space("G1 Old Generation:", oldRegionNum, 230 g1mm.oldUsed(), g1mm.oldCommitted()); 231 } 232 233 private void printG1Space(String spaceName, long regionNum, 234 long used, long capacity) { 235 long free = capacity - used; 236 System.out.println(spaceName); 237 printValue("regions = ", regionNum); 238 printValMB("capacity = ", capacity); 239 printValMB("used = ", used); 240 printValMB("free = ", free); 241 double occPerc = (capacity > 0) ? (double) used * 100.0 / capacity : 0.0; 242 System.out.println(alignment + occPerc + "% used"); 243 } 244 245 private static final double FACTOR = 1024*1024; 246 private void printValMB(String title, long value) { 247 if (value < 0) { 248 System.out.println(alignment + title + (value >>> 20) + " MB"); 249 } else { 250 double mb = value/FACTOR; 251 System.out.println(alignment + title + value + " (" + mb + "MB)"); 252 } 253 } 254 255 private void printValue(String title, long value) { 256 System.out.println(alignment + title + value); 257 } 258 259 private long getFlagValue(String name, Map flagMap) { 260 VM.Flag f = (VM.Flag) flagMap.get(name); 261 if (f != null) { 262 if (f.isBool()) { 263 return f.getBool()? 1L : 0L; 264 } else { 265 return Long.parseLong(f.getValue()); 266 } 267 } else { 268 return -1; 269 } 270 } 271 272 private void printInternStringStatistics() { 273 class StringStat implements StringTable.StringVisitor { 274 private int count; 275 private long size; 276 private OopField stringValueField; 277 278 StringStat() { 279 VM vm = VM.getVM(); 280 SystemDictionary sysDict = vm.getSystemDictionary(); 281 InstanceKlass strKlass = sysDict.getStringKlass(); 282 // String has a field named 'value' of type 'byte[]'. 283 stringValueField = (OopField) strKlass.findField("value", "[B"); 284 } 285 286 private long stringSize(Instance instance) { 287 // We include String content in size calculation. 288 return instance.getObjectSize() + 289 stringValueField.getValue(instance).getObjectSize(); 290 } 291 292 public void visit(Instance str) { 293 count++; 294 size += stringSize(str); 295 } 296 297 public void print() { 298 System.out.println(count + 299 " interned Strings occupying " + size + " bytes."); 300 } 301 } 302 303 StringStat stat = new StringStat(); 304 StringTable strTable = VM.getVM().getStringTable(); 305 strTable.stringsDo(stat); 306 stat.print(); 307 } 308 }