/* * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
publicstaticvoid main(String[] args) throws Exception { // Create a stopped recording in the repository to complicate things
Recording r = new Recording();
r.start();
StoppedEvent de = new StoppedEvent();
de.commit();
r.stop();
// The implementation of JFR.dump touch code that can't be executed using the // Java API. It is therefore important to try all combinations. The // implementation is non-trivial and depends on the combination for (String name : names) { for (boolean disk : booleanValues) { try (Recording r1 = new Recording(); Recording r2 = new Recording()) {
System.out.println();
System.out.println();
System.out.println("Starting recordings with disk=" + disk);
r1.setToDisk(disk); // To complicate things, only enable OldObjectSample for one recording
r1.enable(EventNames.OldObjectSample).withoutStackTrace();
r1.setName("r1");
r2.setToDisk(disk);
r2.setName("r2");
r1.start();
r2.start();
// Expect no path to GC roots
jfrDump(Boolean.FALSE, name, disk, rootCount -> rootCount == 0); // Expect path to GC roots
jfrDump(null, name, disk, rootCount -> rootCount == 0); // Expect at least one path to a GC root
jfrDump(Boolean.TRUE, name, disk, rootCount -> rootCount > 0);
}
}
}
r.close(); // release recording data from the stopped recording
}
privatestaticvoid jfrDump(Boolean pathToGCRoots, String name, boolean disk, Predicate<Integer> successPredicate) throws Exception {
List<Object> leakList = new ArrayList<>();
leakList.add(new Object[1000_0000]);
System.gc(); while (true) {
RunningEvent re = new RunningEvent();
re.commit();
leakList.add(new Object[1000_0000]);
leakList.add(new Object[1000_0000]);
leakList.add(new Object[1000_0000]);
System.gc(); // This will shorten time for object to be emitted.
File recording = new File("TestJCMdDump.jfr");
List<String> params = buildParameters(pathToGCRoots, name, recording);
System.out.println(params);
OutputAnalyzer output = ProcessTools.executeProcess(new ProcessBuilder(params));
output.reportDiagnosticSummary();
JcmdAsserts.assertRecordingDumpedToFile(output, recording); int rootCount = 0; int oldObjectCount = 0; int stoppedEventCount = 0; int runningEventCount = 0; for (RecordedEvent e : RecordingFile.readAllEvents(recording.toPath())) { if (e.getEventType().getName().equals(EventNames.OldObjectSample)) { if (e.getValue("root") != null) {
rootCount++;
}
oldObjectCount++;
} if (e.getEventType().getName().equals(StoppedEvent.class.getName())) {
stoppedEventCount++;
} if (e.getEventType().getName().equals(RunningEvent.class.getName())) {
runningEventCount++;
}
}
System.out.println("Name: " + name);
System.out.println("Disk: " + disk);
System.out.println("Path to GC roots: " + pathToGCRoots);
System.out.println("Old Objects: " + oldObjectCount);
System.out.println("Root objects: "+ rootCount);
System.out.println("Stopped events: "+ stoppedEventCount);
System.out.println("Running events: "+ runningEventCount);
System.out.println(); if (runningEventCount == 0) { thrownew Exception("Missing event from running recording");
} if (name == null && stoppedEventCount == 0) { thrownew Exception("Missing event from stopped recording");
} if (name != null && stoppedEventCount > 0) { thrownew Exception("Stopped event should not be part of dump");
} if (oldObjectCount != 0 && successPredicate.test(rootCount)) { return;
}
System.out.println();
System.out.println();
System.out.println();
System.out.println("************* Retrying! **************");
Files.delete(recording.toPath());
}
}
privatestatic List<String> buildParameters(Boolean pathToGCRoots, String name, File recording) {
List<String> params = new ArrayList<>();
params.add(JDKToolFinder.getJDKTool("jcmd"));
params.add("-J-Dsun.tools.attach.attachTimeout=" + timeoutMillis);
params.add(String.valueOf(ProcessHandle.current().pid()));
params.add("JFR.dump");
params.add("filename=" + recording.getAbsolutePath()); if (pathToGCRoots != null) { // if path-to-gc-roots is omitted, default is used (disabled).
params.add("path-to-gc-roots=" + pathToGCRoots);
} if (name != null) { // if name is omitted, all recordings will be dumped
params.add("name=" + name);
} return params;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.