1 /* 2 * Copyright (c) 2005, 2020, 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 import static jdk.test.lib.Asserts.assertTrue; 25 import static jdk.test.lib.Asserts.assertFalse; 26 import static jdk.test.lib.Asserts.fail; 27 28 import java.io.File; 29 import java.nio.file.Files; 30 import java.util.Arrays; 31 import java.util.List; 32 33 import jdk.test.lib.JDKToolLauncher; 34 import jdk.test.lib.Utils; 35 import jdk.test.lib.hprof.HprofParser; 36 import jdk.test.lib.process.OutputAnalyzer; 37 import jdk.test.lib.process.ProcessTools; 38 39 /* 40 * @test id=Serial 41 * @requires vm.gc.Serial 42 * @summary Unit test for jmap utility (Serial GC) 43 * @key intermittent 44 * @library /test/lib 45 * @build jdk.test.lib.hprof.* 46 * @build jdk.test.lib.hprof.model.* 47 * @build jdk.test.lib.hprof.parser.* 48 * @build jdk.test.lib.hprof.util.* 49 * @run main/othervm/timeout=240 -XX:+UseSerialGC BasicJMapTest 50 */ 51 52 /* 53 * @test id=Parallel 54 * @requires vm.gc.Parallel 55 * @summary Unit test for jmap utility (Parallel GC) 56 * @key intermittent 57 * @library /test/lib 58 * @build jdk.test.lib.hprof.* 59 * @build jdk.test.lib.hprof.model.* 60 * @build jdk.test.lib.hprof.parser.* 61 * @build jdk.test.lib.hprof.util.* 62 * @run main/othervm/timeout=240 -XX:+UseParallelGC BasicJMapTest 63 */ 64 65 /* 66 * @test id=G1 67 * @requires vm.gc.G1 68 * @summary Unit test for jmap utility (G1 GC) 69 * @key intermittent 70 * @library /test/lib 71 * @build jdk.test.lib.hprof.* 72 * @build jdk.test.lib.hprof.model.* 73 * @build jdk.test.lib.hprof.parser.* 74 * @build jdk.test.lib.hprof.util.* 75 * @run main/othervm/timeout=240 -XX:+UseG1GC BasicJMapTest 76 */ 77 78 /* 79 * @test id=Shenandoah 80 * @requires vm.gc.Shenandoah 81 * @summary Unit test for jmap utility (Shenandoah GC) 82 * @key intermittent 83 * @library /test/lib 84 * @build jdk.test.lib.hprof.* 85 * @build jdk.test.lib.hprof.model.* 86 * @build jdk.test.lib.hprof.parser.* 87 * @build jdk.test.lib.hprof.util.* 88 * @run main/othervm/timeout=240 -XX:+UseShenandoahGC BasicJMapTest 89 */ 90 91 /* 92 * @test id=Z 93 * @requires vm.gc.Z 94 * @summary Unit test for jmap utility (Z GC) 95 * @key intermittent 96 * @library /test/lib 97 * @build jdk.test.lib.hprof.* 98 * @build jdk.test.lib.hprof.model.* 99 * @build jdk.test.lib.hprof.parser.* 100 * @build jdk.test.lib.hprof.util.* 101 * @run main/othervm/timeout=240 -XX:+UseZGC BasicJMapTest 102 */ 103 104 public class BasicJMapTest { 105 106 private static ProcessBuilder processBuilder = new ProcessBuilder(); 107 main(String[] args)108 public static void main(String[] args) throws Exception { 109 testHisto(); 110 testHistoLive(); 111 testHistoAll(); 112 testHistoToFile(); 113 testHistoLiveToFile(); 114 testHistoAllToFile(); 115 testFinalizerInfo(); 116 testClstats(); 117 testDump(); 118 testDumpLive(); 119 testDumpAll(); 120 testDumpCompressed(); 121 } 122 testHisto()123 private static void testHisto() throws Exception { 124 OutputAnalyzer output = jmap("-histo:"); 125 output.shouldHaveExitValue(0); 126 OutputAnalyzer output1 = jmap("-histo"); 127 output1.shouldHaveExitValue(0); 128 } 129 testHistoLive()130 private static void testHistoLive() throws Exception { 131 OutputAnalyzer output = jmap("-histo:live"); 132 output.shouldHaveExitValue(0); 133 } 134 testHistoAll()135 private static void testHistoAll() throws Exception { 136 OutputAnalyzer output = jmap("-histo:all"); 137 output.shouldHaveExitValue(0); 138 } 139 testHistoParallelZero()140 private static void testHistoParallelZero() throws Exception { 141 OutputAnalyzer output = jmap("-histo:parallel=0"); 142 output.shouldHaveExitValue(0); 143 } 144 testHistoParallel()145 private static void testHistoParallel() throws Exception { 146 OutputAnalyzer output = jmap("-histo:parallel=2"); 147 output.shouldHaveExitValue(0); 148 } 149 testHistoNonParallel()150 private static void testHistoNonParallel() throws Exception { 151 OutputAnalyzer output = jmap("-histo:parallel=1"); 152 output.shouldHaveExitValue(0); 153 } 154 testHistoToFile()155 private static void testHistoToFile() throws Exception { 156 histoToFile(false, false, 1); 157 } 158 testHistoLiveToFile()159 private static void testHistoLiveToFile() throws Exception { 160 histoToFile(true, false, 1); 161 } 162 testHistoAllToFile()163 private static void testHistoAllToFile() throws Exception { 164 histoToFile(false, true, 1); 165 } 166 testHistoFileParallelZero()167 private static void testHistoFileParallelZero() throws Exception { 168 histoToFile(false, false, 0); 169 } 170 testHistoFileParallel()171 private static void testHistoFileParallel() throws Exception { 172 histoToFile(false, false, 2); 173 } 174 histoToFile(boolean live, boolean explicitAll, int parallelThreadNum)175 private static void histoToFile(boolean live, 176 boolean explicitAll, 177 int parallelThreadNum) throws Exception { 178 String liveArg = ""; 179 String fileArg = ""; 180 String parArg = "parallel=" + parallelThreadNum; 181 String allArgs = "-histo:"; 182 183 if (live && explicitAll) { 184 fail("Illegal argument setting for jmap -histo"); 185 } 186 if (live) { 187 liveArg = "live,"; 188 } 189 if (explicitAll) { 190 liveArg = "all,"; 191 } 192 193 File file = new File("jmap.histo.file" + System.currentTimeMillis() + ".histo"); 194 if (file.exists()) { 195 file.delete(); 196 } 197 fileArg = "file=" + file.getName(); 198 199 OutputAnalyzer output; 200 allArgs = allArgs + liveArg + fileArg + ',' + parArg; 201 output = jmap(allArgs); 202 output.shouldHaveExitValue(0); 203 output.shouldContain("Heap inspection file created"); 204 file.delete(); 205 } 206 testFinalizerInfo()207 private static void testFinalizerInfo() throws Exception { 208 OutputAnalyzer output = jmap("-finalizerinfo"); 209 output.shouldHaveExitValue(0); 210 } 211 testClstats()212 private static void testClstats() throws Exception { 213 OutputAnalyzer output = jmap("-clstats"); 214 output.shouldHaveExitValue(0); 215 } 216 testDump()217 private static void testDump() throws Exception { 218 dump(false, false, false); 219 } 220 testDumpLive()221 private static void testDumpLive() throws Exception { 222 dump(true, false, false); 223 } 224 testDumpAll()225 private static void testDumpAll() throws Exception { 226 dump(false, true, false); 227 } 228 testDumpCompressed()229 private static void testDumpCompressed() throws Exception { 230 dump(true, false, true); 231 } 232 dump(boolean live, boolean explicitAll, boolean compressed)233 private static void dump(boolean live, boolean explicitAll, boolean compressed) throws Exception { 234 String liveArg = ""; 235 String fileArg = ""; 236 String compressArg = ""; 237 String allArgs = "-dump:"; 238 239 if (live && explicitAll) { 240 fail("Illegal argument setting for jmap -dump"); 241 } 242 if (live) { 243 liveArg = "live,"; 244 } 245 if (explicitAll) { 246 liveArg = "all,"; 247 } 248 249 String filePath = "jmap.dump" + System.currentTimeMillis() + ".hprof"; 250 if (compressed) { 251 compressArg = "gz=1,"; 252 filePath = filePath + ".gz"; 253 } 254 255 File file = new File(filePath); 256 if (file.exists()) { 257 file.delete(); 258 } 259 fileArg = "file=" + file.getName(); 260 261 OutputAnalyzer output; 262 allArgs = allArgs + liveArg + compressArg + "format=b," + fileArg; 263 output = jmap(allArgs); 264 output.shouldHaveExitValue(0); 265 output.shouldContain("Heap dump file created"); 266 verifyDumpFile(file); 267 file.delete(); 268 } 269 verifyDumpFile(File dump)270 private static void verifyDumpFile(File dump) { 271 assertTrue(dump.exists() && dump.isFile(), "Could not create dump file " + dump.getAbsolutePath()); 272 try { 273 File out = HprofParser.parse(dump); 274 275 assertTrue(out != null && out.exists() && out.isFile(), 276 "Could not find hprof parser output file"); 277 List<String> lines = Files.readAllLines(out.toPath()); 278 assertTrue(lines.size() > 0, "hprof parser output file is empty"); 279 for (String line : lines) { 280 assertFalse(line.matches(".*WARNING(?!.*Failed to resolve " + 281 "object.*constantPoolOop.*).*")); 282 } 283 284 out.delete(); 285 } catch (Exception e) { 286 e.printStackTrace(); 287 fail("Could not parse dump file " + dump.getAbsolutePath()); 288 } 289 } 290 jmap(String... toolArgs)291 private static OutputAnalyzer jmap(String... toolArgs) throws Exception { 292 JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jmap"); 293 launcher.addVMArgs(Utils.getTestJavaOpts()); 294 if (toolArgs != null) { 295 for (String toolArg : toolArgs) { 296 launcher.addToolArg(toolArg); 297 } 298 } 299 launcher.addToolArg(Long.toString(ProcessTools.getProcessId())); 300 301 processBuilder.command(launcher.getCommand()); 302 System.out.println(Arrays.toString(processBuilder.command().toArray())); 303 OutputAnalyzer output = ProcessTools.executeProcess(processBuilder); 304 System.out.println(output.getOutput()); 305 306 return output; 307 } 308 } 309