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