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.runtime.*;
  34 
  35 public class HeapSummary extends Tool {
  36 
  37    public static void main(String[] args) {
  38       HeapSummary hs = new HeapSummary();
  39       hs.start(args);
  40       hs.stop();
  41    }
  42 
  43    public void run() {
  44       CollectedHeap heap = VM.getVM().getUniverse().heap();
  45       VM.Flag[] flags = VM.getVM().getCommandLineFlags();
  46       Map flagMap = new HashMap();
  47       if (flags == null) {
  48          System.out.println("WARNING: command line flags are not available");
  49       } else {
  50          for (int f = 0; f < flags.length; f++) {
  51             flagMap.put(flags[f].getName(), flags[f]);
  52          }
  53       }
  54 
  55       System.out.println();
  56       printGCAlgorithm(flagMap);
  57       System.out.println();
  58       System.out.println("Heap Configuration:");
  59       printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap));
  60       printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap));
  61       printValMB("MaxHeapSize      = ", getFlagValue("MaxHeapSize", flagMap));
  62       printValMB("NewSize          = ", getFlagValue("NewSize", flagMap));
  63       printValMB("MaxNewSize       = ", getFlagValue("MaxNewSize", flagMap));
  64       printValMB("OldSize          = ", getFlagValue("OldSize", flagMap));
  65       printValue("NewRatio         = ", getFlagValue("NewRatio", flagMap));
  66       printValue("SurvivorRatio    = ", getFlagValue("SurvivorRatio", flagMap));
  67       printValMB("PermSize         = ", getFlagValue("PermSize", flagMap));
  68       printValMB("MaxPermSize      = ", getFlagValue("MaxPermSize", flagMap));
  69 
  70       System.out.println();
  71       System.out.println("Heap Usage:");
  72 
  73       if (heap instanceof SharedHeap) {
  74          SharedHeap sharedHeap = (SharedHeap) heap;
  75          if (sharedHeap instanceof GenCollectedHeap) {
  76             GenCollectedHeap genHeap = (GenCollectedHeap) sharedHeap;
  77             for (int n = 0; n < genHeap.nGens(); n++) {
  78                Generation gen = genHeap.getGen(n);
  79                if (gen instanceof sun.jvm.hotspot.memory.DefNewGeneration) {
  80                   System.out.println("New Generation (Eden + 1 Survivor Space):");
  81                   printGen(gen);
  82 
  83                   ContiguousSpace eden = ((DefNewGeneration)gen).eden();
  84                   System.out.println("Eden Space:");
  85                   printSpace(eden);
  86 
  87                   ContiguousSpace from = ((DefNewGeneration)gen).from();
  88                   System.out.println("From Space:");
  89                   printSpace(from);
  90 
  91                   ContiguousSpace to = ((DefNewGeneration)gen).to();
  92                   System.out.println("To Space:");
  93                   printSpace(to);
  94                } else {
  95                   System.out.println(gen.name() + ":");
  96                   printGen(gen);
  97                }
  98             }
  99          } else if (sharedHeap instanceof G1CollectedHeap) {
 100              G1CollectedHeap g1h = (G1CollectedHeap) sharedHeap;
 101              G1MonitoringSupport g1mm = g1h.g1mm();
 102              System.out.println("G1 Young Generation");
 103              printG1Space("Eden Space:", g1mm.edenUsed(), g1mm.edenCommitted());
 104              printG1Space("From Space:", g1mm.survivorUsed(), g1mm.survivorCommitted());
 105              printG1Space("To Space:", 0, 0);
 106              printG1Space("G1 Old Generation", g1mm.oldUsed(), g1mm.oldCommitted());
 107          } else {
 108              throw new RuntimeException("unknown SharedHeap type : " + heap.getClass());
 109          }
 110          // Perm generation shared by the above
 111          Generation permGen = sharedHeap.permGen();
 112          System.out.println("Perm Generation:");
 113          printGen(permGen);
 114       } else if (heap instanceof ParallelScavengeHeap) {
 115          ParallelScavengeHeap psh = (ParallelScavengeHeap) heap;
 116          PSYoungGen youngGen = psh.youngGen();
 117          printPSYoungGen(youngGen);
 118 
 119          PSOldGen oldGen = psh.oldGen();
 120          long oldFree = oldGen.capacity() - oldGen.used();
 121          System.out.println("PS Old Generation");
 122          printValMB("capacity = ", oldGen.capacity());
 123          printValMB("used     = ", oldGen.used());
 124          printValMB("free     = ", oldFree);
 125          System.out.println(alignment + (double)oldGen.used() * 100.0 / oldGen.capacity() + "% used");
 126 
 127          PSPermGen permGen = psh.permGen();
 128          long permFree = permGen.capacity() - permGen.used();
 129          System.out.println("PS Perm Generation");
 130          printValMB("capacity = ", permGen.capacity());
 131          printValMB("used     = ", permGen.used());
 132          printValMB("free     = ", permFree);
 133          System.out.println(alignment + (double)permGen.used() * 100.0 / permGen.capacity() + "% used");
 134       } else {
 135          throw new RuntimeException("unknown CollectedHeap type : " + heap.getClass());
 136       }
 137    }
 138 
 139    // Helper methods
 140 
 141    private void printGCAlgorithm(Map flagMap) {
 142        // print about new generation
 143        long l = getFlagValue("UseParNewGC", flagMap);
 144        if (l == 1L) {
 145           System.out.println("using parallel threads in the new generation.");
 146        }
 147 
 148        l = getFlagValue("UseTLAB", flagMap);
 149        if (l == 1L) {
 150           System.out.println("using thread-local object allocation.");
 151        }
 152 
 153        l = getFlagValue("UseConcMarkSweepGC", flagMap);
 154        if (l == 1L) {
 155           System.out.println("Concurrent Mark-Sweep GC");
 156           return;
 157        }
 158 
 159        l = getFlagValue("UseParallelGC", flagMap);
 160        if (l == 1L) {
 161           System.out.print("Parallel GC ");
 162           l = getFlagValue("ParallelGCThreads", flagMap);
 163           System.out.println("with " + l + " thread(s)");
 164           return;
 165        }
 166 
 167        l = getFlagValue("UseG1GC", flagMap);
 168        if (l == 1L) {
 169            System.out.print("Garbage-First (G1) GC ");
 170            l = getFlagValue("ParallelGCThreads", flagMap);
 171            System.out.println("with " + l + " thread(s)");
 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    private void printG1Space(String spaceName, long used, long capacity) {
 216       long free = capacity - used;
 217       System.out.println(spaceName);
 218       printValMB("capacity = ", capacity);
 219       printValMB("used     = ", used);
 220       printValMB("free     = ", free);
 221       double occPerc = (capacity > 0) ? (double) used * 100.0 / capacity : 0.0;
 222       System.out.println(alignment + occPerc + "% used");
 223    }
 224 
 225    private static final double FACTOR = 1024*1024;
 226    private void printValMB(String title, long value) {
 227       if (value < 0) {
 228         System.out.println(alignment + title +   (value >>> 20)  + " MB");
 229       } else {
 230         double mb = value/FACTOR;
 231         System.out.println(alignment + title + value + " (" + mb + "MB)");
 232       }
 233    }
 234 
 235    private void printValue(String title, long value) {
 236       System.out.println(alignment + title + value);
 237    }
 238 
 239    private long getFlagValue(String name, Map flagMap) {
 240       VM.Flag f = (VM.Flag) flagMap.get(name);
 241       if (f != null) {
 242          if (f.isBool()) {
 243             return f.getBool()? 1L : 0L;
 244          } else {
 245             return Long.parseLong(f.getValue());
 246          }
 247       } else {
 248          return -1;
 249       }
 250    }
 251 }