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