TestInstanceKlassSize.java revision 12290:8953c0318163
1/* 2 * Copyright (c) 2015, 2016, 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 24import sun.jvm.hotspot.HotSpotAgent; 25import sun.jvm.hotspot.utilities.SystemDictionaryHelper; 26import sun.jvm.hotspot.oops.InstanceKlass; 27import sun.jvm.hotspot.debugger.*; 28 29import java.util.ArrayList; 30import java.util.List; 31import java.util.stream.Collectors; 32 33import jdk.test.lib.JDKToolLauncher; 34import jdk.test.lib.Platform; 35import jdk.test.lib.process.ProcessTools; 36import jdk.test.lib.process.OutputAnalyzer; 37import jdk.test.lib.Utils; 38import jdk.test.lib.apps.LingeredApp; 39import jdk.test.lib.Asserts; 40 41import java.io.*; 42import java.util.*; 43 44/* 45 * @test 46 * @library /test/lib 47 * @modules java.base/jdk.internal.misc 48 * @compile -XDignore.symbol.file=true 49 * --add-modules=jdk.hotspot.agent 50 * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED 51 * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED 52 * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED 53 * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED 54 * TestInstanceKlassSize.java 55 * @run main/othervm 56 * --add-modules=jdk.hotspot.agent 57 * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED 58 * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED 59 * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED 60 * --add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED 61 * TestInstanceKlassSize 62 */ 63 64public class TestInstanceKlassSize { 65 66 private static String getJcmdInstanceKlassSize(OutputAnalyzer output, 67 String instanceKlassName) { 68 for (String s : output.asLines()) { 69 if (s.contains(instanceKlassName)) { 70 String tokens[]; 71 System.out.println(s); 72 tokens = s.split("\\s+"); 73 return tokens[3]; 74 } 75 } 76 return null; 77 } 78 79 private static OutputAnalyzer jcmd(Long pid, 80 String... toolArgs) throws Exception { 81 ProcessBuilder processBuilder = new ProcessBuilder(); 82 JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jcmd"); 83 launcher.addToolArg(Long.toString(pid)); 84 if (toolArgs != null) { 85 for (String toolArg : toolArgs) { 86 launcher.addToolArg(toolArg); 87 } 88 } 89 90 processBuilder.command(launcher.getCommand()); 91 System.out.println( 92 processBuilder.command().stream().collect(Collectors.joining(" "))); 93 return ProcessTools.executeProcess(processBuilder); 94 } 95 96 private static void startMeWithArgs() throws Exception { 97 98 LingeredApp app = null; 99 OutputAnalyzer output = null; 100 try { 101 List<String> vmArgs = new ArrayList<String>(); 102 vmArgs.add("-XX:+UsePerfData"); 103 vmArgs.addAll(Utils.getVmOptions()); 104 app = LingeredApp.startApp(vmArgs); 105 System.out.println ("Started LingeredApp with pid " + app.getPid()); 106 } catch (Exception ex) { 107 ex.printStackTrace(); 108 throw new RuntimeException(ex); 109 } 110 try { 111 String[] instanceKlassNames = new String[] { 112 " java.lang.Object", 113 " java.util.Vector", 114 " sun.util.PreHashedMap", 115 " java.lang.String", 116 " java.lang.Thread", 117 " java.lang.Byte", 118 }; 119 String[] toolArgs = { 120 "--add-modules=jdk.hotspot.agent", 121 "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED", 122 "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED", 123 "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED", 124 "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED", 125 "TestInstanceKlassSize", 126 Long.toString(app.getPid()) 127 }; 128 129 OutputAnalyzer jcmdOutput = jcmd( 130 app.getPid(), 131 "GC.class_stats", "VTab,ITab,OopMap,KlassBytes"); 132 ProcessBuilder processBuilder = ProcessTools 133 .createJavaProcessBuilder(toolArgs); 134 output = ProcessTools.executeProcess(processBuilder); 135 System.out.println(output.getOutput()); 136 output.shouldHaveExitValue(0); 137 138 // Check whether the size matches that which jcmd outputs 139 for (String instanceKlassName : instanceKlassNames) { 140 System.out.println ("Trying to match for" + instanceKlassName); 141 String jcmdInstanceKlassSize = getJcmdInstanceKlassSize( 142 jcmdOutput, 143 instanceKlassName); 144 Asserts.assertNotNull(jcmdInstanceKlassSize, 145 "Could not get the instance klass size from the jcmd output"); 146 for (String s : output.asLines()) { 147 if (s.contains(instanceKlassName)) { 148 Asserts.assertTrue( 149 s.contains(jcmdInstanceKlassSize), 150 "The size computed by SA for" + 151 instanceKlassName + " does not match."); 152 } 153 } 154 } 155 } finally { 156 LingeredApp.stopApp(app); 157 } 158 } 159 160 private static void SAInstanceKlassSize(int pid, 161 String[] SAInstanceKlassNames) { 162 HotSpotAgent agent = new HotSpotAgent(); 163 try { 164 agent.attach(pid); 165 } 166 catch (DebuggerException e) { 167 System.out.println(e.getMessage()); 168 System.err.println("Unable to connect to process ID: " + pid); 169 170 agent.detach(); 171 e.printStackTrace(); 172 } 173 174 for (String SAInstanceKlassName : SAInstanceKlassNames) { 175 InstanceKlass ik = SystemDictionaryHelper.findInstanceKlass( 176 SAInstanceKlassName); 177 Asserts.assertNotNull(ik, 178 String.format("Unable to find instance klass for %s", ik)); 179 System.out.println("SA: The size of " + SAInstanceKlassName + 180 " is " + ik.getSize()); 181 } 182 agent.detach(); 183 } 184 185 public static void main(String[] args) throws Exception { 186 187 if (!Platform.shouldSAAttach()) { 188 System.out.println("SA attach not expected to work - test skipped."); 189 return; 190 } 191 192 if (args == null || args.length == 0) { 193 System.out.println ("No args run. Starting with args now."); 194 startMeWithArgs(); 195 } else { 196 String[] SAInstanceKlassNames = new String[] { 197 "java.lang.Object", 198 "java.util.Vector", 199 "sun.util.PreHashedMap", 200 "java.lang.String", 201 "java.lang.Thread", 202 "java.lang.Byte" 203 }; 204 SAInstanceKlassSize(Integer.parseInt(args[0]), SAInstanceKlassNames); 205 } 206 } 207} 208 209