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