1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2018, SAP and/or its affiliates. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 import jdk.test.lib.process.ProcessTools;
  26 import jdk.test.lib.process.OutputAnalyzer;
  27 import jdk.test.lib.JDKToolFinder;
  28 
  29 /*
  30  * @test
  31  * @key metaspace jcmd
  32  * @summary Test the VM.metaspace command
  33  * @library /test/lib
  34  * @modules java.base/jdk.internal.misc
  35  *          java.management
  36  * @run main/othervm -XX:MaxMetaspaceSize=201M -Xmx100M -XX:+UseCompressedOops -XX:+UseCompressedClassPointers PrintMetaspaceDcmd with-compressed-class-space
  37  * @run main/othervm -XX:MaxMetaspaceSize=201M -Xmx100M -XX:-UseCompressedOops -XX:-UseCompressedClassPointers PrintMetaspaceDcmd without-compressed-class-space
  38  */
  39 
  40 public class PrintMetaspaceDcmd {
  41 
  42     // Run jcmd VM.metaspace against a VM with CompressedClassPointers on.
  43     // The report should detail Non-Class and Class portions separately.
  44     private static void doTheTest(boolean usesCompressedClassSpace) throws Exception {
  45         ProcessBuilder pb = new ProcessBuilder();
  46         OutputAnalyzer output;
  47         // Grab my own PID
  48         String pid = Long.toString(ProcessTools.getProcessId());
  49 
  50         pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.metaspace", "basic"});
  51         output = new OutputAnalyzer(pb.start());
  52         output.shouldHaveExitValue(0);
  53         if (usesCompressedClassSpace) {
  54             output.shouldContain("Non-Class:");
  55             output.shouldContain("Class:");
  56         }
  57         output.shouldContain("Virtual space:");
  58         output.shouldContain("Chunk freelists:");
  59 
  60 
  61         pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.metaspace"});
  62         output = new OutputAnalyzer(pb.start());
  63         output.shouldHaveExitValue(0);
  64         if (usesCompressedClassSpace) {
  65             output.shouldContain("Non-Class:");
  66             output.shouldContain("Class:");
  67         }
  68         output.shouldContain("Virtual space:");
  69         output.shouldContain("Chunk freelist");
  70         output.shouldContain("Waste");
  71         output.shouldMatch("MaxMetaspaceSize:.*201.00.*MB");
  72 
  73         pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.metaspace", "show-loaders"});
  74         output = new OutputAnalyzer(pb.start());
  75         output.shouldHaveExitValue(0);
  76         output.shouldMatch("CLD.*<bootstrap>");
  77 
  78         pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.metaspace", "by-chunktype"});
  79         output = new OutputAnalyzer(pb.start());
  80         output.shouldHaveExitValue(0);
  81         output.shouldContain("specialized:");
  82         output.shouldContain("small:");
  83         output.shouldContain("medium:");
  84         output.shouldContain("humongous:");
  85 
  86         pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.metaspace", "vslist"});
  87         output = new OutputAnalyzer(pb.start());
  88         output.shouldHaveExitValue(0);
  89         output.shouldContain("Virtual space list");
  90         output.shouldMatch("node.*reserved.*committed.*used.*");
  91 
  92         pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.metaspace", "vsmap"});
  93         output = new OutputAnalyzer(pb.start());
  94         output.shouldHaveExitValue(0);
  95         output.shouldContain("Virtual space map:");
  96         output.shouldContain("HHHHHHHHHHH");
  97 
  98         // Test with different scales
  99         pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.metaspace", "scale=G"});
 100         output = new OutputAnalyzer(pb.start());
 101         output.shouldHaveExitValue(0);
 102         output.shouldMatch("MaxMetaspaceSize:.*0.2.*GB");
 103 
 104         pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.metaspace", "scale=K"});
 105         output = new OutputAnalyzer(pb.start());
 106         output.shouldHaveExitValue(0);
 107         output.shouldMatch("MaxMetaspaceSize:.*205824.00 KB");
 108 
 109         pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.metaspace", "scale=1"});
 110         output = new OutputAnalyzer(pb.start());
 111         output.shouldHaveExitValue(0);
 112         output.shouldMatch("MaxMetaspaceSize:.*210763776 bytes");
 113     }
 114 
 115     public static void main(String args[]) throws Exception {
 116         boolean testForCompressedClassSpace = false;
 117         if (args[0].equals("with-compressed-class-space")) {
 118             testForCompressedClassSpace = true;
 119         } else if (args[0].equals("without-compressed-class-space")) {
 120             testForCompressedClassSpace = false;
 121         } else {
 122             throw new IllegalArgumentException("Invalid argument: " + args[0]);
 123         }
 124         doTheTest(testForCompressedClassSpace);
 125     }
 126 }