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.gc.z.*; 34 import sun.jvm.hotspot.debugger.JVMDebugger; 35 import sun.jvm.hotspot.memory.*; 36 import sun.jvm.hotspot.oops.*; 37 import sun.jvm.hotspot.runtime.*; 38 39 public class HeapSummary extends Tool { 40 41 public HeapSummary() { 42 super(); 43 } 44 45 public HeapSummary(JVMDebugger d) { 46 super(d); 47 } 48 49 public static void main(String[] args) { 50 HeapSummary hs = new HeapSummary(); 51 hs.execute(args); 52 } 53 54 @Override 55 public String getName() { 56 return "heapSummary"; 57 } 58 59 public void run() { 60 CollectedHeap heap = VM.getVM().getUniverse().heap(); 61 VM.Flag[] flags = VM.getVM().getCommandLineFlags(); 62 Map flagMap = new HashMap(); 63 if (flags == null) { 64 System.out.println("WARNING: command line flags are not available"); 65 } else { 66 for (int f = 0; f < flags.length; f++) { 67 flagMap.put(flags[f].getName(), flags[f]); 68 } 69 } 70 71 System.out.println(); 72 printGCAlgorithm(flagMap); 73 System.out.println(); 74 System.out.println("Heap Configuration:"); 75 printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap)); 76 printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap)); 77 printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap)); 78 printValMB("NewSize = ", getFlagValue("NewSize", flagMap)); 79 printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap)); 80 printValMB("OldSize = ", getFlagValue("OldSize", flagMap)); 81 printValue("NewRatio = ", getFlagValue("NewRatio", flagMap)); 82 printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap)); 83 printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap)); 84 printValMB("CompressedClassSpaceSize = ", getFlagValue("CompressedClassSpaceSize", flagMap)); 85 printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap)); 86 printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes()); 87 88 System.out.println(); 89 System.out.println("Heap Usage:"); 90 91 if (heap instanceof GenCollectedHeap) { 92 GenCollectedHeap genHeap = (GenCollectedHeap) heap; 93 for (int n = 0; n < genHeap.nGens(); n++) { 94 Generation gen = genHeap.getGen(n); 95 if (gen instanceof 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 (heap instanceof G1CollectedHeap) { 116 printG1HeapSummary((G1CollectedHeap)heap); 117 } else if (heap instanceof ParallelScavengeHeap) { 118 ParallelScavengeHeap psh = (ParallelScavengeHeap) heap; 119 PSYoungGen youngGen = psh.youngGen(); 120 printPSYoungGen(youngGen); 121 122 PSOldGen oldGen = psh.oldGen(); 123 long oldFree = oldGen.capacity() - oldGen.used(); 124 System.out.println("PS Old Generation"); 125 printValMB("capacity = ", oldGen.capacity()); 126 printValMB("used = ", oldGen.used()); 127 printValMB("free = ", oldFree); 128 System.out.println(alignment + (double)oldGen.used() * 100.0 / oldGen.capacity() + "% used"); 129 } else if (heap instanceof EpsilonHeap) { 130 EpsilonHeap eh = (EpsilonHeap) heap; 131 printSpace(eh.space()); 132 } else if (heap instanceof ZCollectedHeap) { 133 ZCollectedHeap zheap = (ZCollectedHeap) heap; 134 zheap.printOn(System.out); 135 } else { 136 throw new RuntimeException("unknown CollectedHeap type : " + heap.getClass()); 137 } 138 139 System.out.println(); 140 } 141 142 // Helper methods 143 144 private void printGCAlgorithm(Map flagMap) { 145 long l = getFlagValue("UseTLAB", flagMap); 146 if (l == 1L) { 147 System.out.println("using thread-local object allocation."); 148 } 149 150 l = getFlagValue("UseConcMarkSweepGC", flagMap); 151 if (l == 1L) { 152 System.out.println("Concurrent Mark-Sweep GC"); 153 return; 154 } 155 156 l = getFlagValue("UseParallelGC", flagMap); 157 if (l == 1L) { 158 System.out.print("Parallel GC "); 159 l = getFlagValue("ParallelGCThreads", flagMap); 160 System.out.println("with " + l + " thread(s)"); 161 return; 162 } 163 164 l = getFlagValue("UseG1GC", flagMap); 165 if (l == 1L) { 166 System.out.print("Garbage-First (G1) GC "); 167 l = getFlagValue("ParallelGCThreads", flagMap); 168 System.out.println("with " + l + " thread(s)"); 169 return; 170 } 171 172 l = getFlagValue("UseEpsilonGC", flagMap); 173 if (l == 1L) { 174 System.out.println("Epsilon (no-op) GC"); 175 return; 176 } 177 178 l = getFlagValue("UseZGC", flagMap); 179 if (l == 1L) { 180 System.out.print("ZGC "); 181 l = getFlagValue("ParallelGCThreads", flagMap); 182 System.out.println("with " + l + " thread(s)"); 183 return; 184 } 185 186 System.out.println("Mark Sweep Compact GC"); 187 } 188 189 private void printPSYoungGen(PSYoungGen youngGen) { 190 System.out.println("PS Young Generation"); 191 MutableSpace eden = youngGen.edenSpace(); 192 System.out.println("Eden Space:"); 193 printMutableSpace(eden); 194 MutableSpace from = youngGen.fromSpace(); 195 System.out.println("From Space:"); 196 printMutableSpace(from); 197 MutableSpace to = youngGen.toSpace(); 198 System.out.println("To Space:"); 199 printMutableSpace(to); 200 } 201 202 private void printMutableSpace(MutableSpace space) { 203 printValMB("capacity = ", space.capacity()); 204 printValMB("used = ", space.used()); 205 long free = space.capacity() - space.used(); 206 printValMB("free = ", free); 207 System.out.println(alignment + (double)space.used() * 100.0 / space.capacity() + "% used"); 208 } 209 210 private static String alignment = " "; 211 212 private void printGen(Generation gen) { 213 printValMB("capacity = ", gen.capacity()); 214 printValMB("used = ", gen.used()); 215 printValMB("free = ", gen.free()); 216 System.out.println(alignment + (double)gen.used() * 100.0 / gen.capacity() + "% used"); 217 } 218 219 private void printSpace(ContiguousSpace space) { 220 printValMB("capacity = ", space.capacity()); 221 printValMB("used = ", space.used()); 222 printValMB("free = ", space.free()); 223 System.out.println(alignment + (double)space.used() * 100.0 / space.capacity() + "% used"); 224 } 225 226 public void printG1HeapSummary(G1CollectedHeap g1h) { 227 G1MonitoringSupport g1mm = g1h.g1mm(); 228 long edenSpaceRegionNum = g1mm.edenSpaceRegionNum(); 229 long survivorSpaceRegionNum = g1mm.survivorSpaceRegionNum(); 230 HeapRegionSetBase oldSet = g1h.oldSet(); 231 HeapRegionSetBase archiveSet = g1h.archiveSet(); 232 HeapRegionSetBase humongousSet = g1h.humongousSet(); 233 long oldGenRegionNum = oldSet.length() + archiveSet.length() + humongousSet.length(); 234 printG1Space("G1 Heap:", g1h.n_regions(), 235 g1h.used(), g1h.capacity()); 236 System.out.println("G1 Young Generation:"); 237 printG1Space("Eden Space:", edenSpaceRegionNum, 238 g1mm.edenSpaceUsed(), g1mm.edenSpaceCommitted()); 239 printG1Space("Survivor Space:", survivorSpaceRegionNum, 240 g1mm.survivorSpaceUsed(), g1mm.survivorSpaceCommitted()); 241 printG1Space("G1 Old Generation:", oldGenRegionNum, 242 g1mm.oldGenUsed(), g1mm.oldGenCommitted()); 243 } 244 245 private void printG1Space(String spaceName, long regionNum, 246 long used, long capacity) { 247 long free = capacity - used; 248 System.out.println(spaceName); 249 printValue("regions = ", regionNum); 250 printValMB("capacity = ", capacity); 251 printValMB("used = ", used); 252 printValMB("free = ", free); 253 double occPerc = (capacity > 0) ? (double) used * 100.0 / capacity : 0.0; 254 System.out.println(alignment + occPerc + "% used"); 255 } 256 257 private static final double FACTOR = 1024*1024; 258 private void printValMB(String title, long value) { 259 if (value < 0) { 260 System.out.println(alignment + title + (value >>> 20) + " MB"); 261 } else { 262 double mb = value/FACTOR; 263 System.out.println(alignment + title + value + " (" + mb + "MB)"); 264 } 265 } 266 267 private void printValue(String title, long value) { 268 System.out.println(alignment + title + value); 269 } 270 271 private long getFlagValue(String name, Map flagMap) { 272 VM.Flag f = (VM.Flag) flagMap.get(name); 273 if (f != null) { 274 if (f.isBool()) { 275 return f.getBool()? 1L : 0L; 276 } else { 277 return Long.parseLong(f.getValue()); 278 } 279 } else { 280 return -1; 281 } 282 } 283 }