Improve behaviour for general usage
Dieser Commit ist enthalten in:
Ursprung
45349e18ed
Commit
37a6b83cca
@ -9,7 +9,7 @@ public class Agent {
|
|||||||
|
|
||||||
public static void premain(String args, Instrumentation inst) {
|
public static void premain(String args, Instrumentation inst) {
|
||||||
if ("start".equals(args)) {
|
if ("start".equals(args)) {
|
||||||
sampler = new Sampler(true);
|
sampler = new Sampler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ public class Agent {
|
|||||||
switch (args) {
|
switch (args) {
|
||||||
case "start":
|
case "start":
|
||||||
if(sampler == null)
|
if(sampler == null)
|
||||||
sampler = new Sampler(false);
|
sampler = new Sampler();
|
||||||
break;
|
break;
|
||||||
case "stop":
|
case "stop":
|
||||||
if(sampler != null)
|
if(sampler != null)
|
||||||
|
@ -3,9 +3,10 @@ package de.steamwar;
|
|||||||
import com.sun.tools.attach.*;
|
import com.sun.tools.attach.*;
|
||||||
import com.sun.tools.attach.spi.AttachProvider;
|
import com.sun.tools.attach.spi.AttachProvider;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
@ -22,29 +23,18 @@ public class Main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
if(args.length == 0) {
|
|
||||||
for(AttachProvider provider : AttachProvider.providers()) {
|
|
||||||
for(VirtualMachineDescriptor vmd : provider.listVirtualMachines()) {
|
|
||||||
System.out.println(vmd.id() + " " + vmd.displayName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
VirtualMachine vm = VirtualMachine.attach(args[0]);
|
VirtualMachine vm = VirtualMachine.attach(args.length > 0 ? args[0] : getVmId());
|
||||||
|
|
||||||
if(args.length == 1 || !"heap".equals(args[1])) {
|
if(args.length > 1 && "heap".equals(args[1])) {
|
||||||
|
vm.loadAgent(jarPath.getAbsolutePath(), "heap");
|
||||||
|
} else {
|
||||||
vm.loadAgent(jarPath.getAbsolutePath(), "start");
|
vm.loadAgent(jarPath.getAbsolutePath(), "start");
|
||||||
|
|
||||||
System.out.println("Press keyboard to stop sampling...");
|
System.out.println("Press keyboard to stop sampling...");
|
||||||
System.in.read();
|
System.in.read();
|
||||||
|
|
||||||
vm.loadAgent(jarPath.getAbsolutePath(), "stop");
|
vm.loadAgent(jarPath.getAbsolutePath(), "stop");
|
||||||
|
|
||||||
new ProcessBuilder("xdot", "samples.dot").directory(jarPath.getParentFile()).start();
|
|
||||||
} else {
|
|
||||||
vm.loadAgent(jarPath.getAbsolutePath(), "heap");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vm.detach();
|
vm.detach();
|
||||||
@ -53,4 +43,16 @@ public class Main {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getVmId() throws IOException {
|
||||||
|
List<String> vms = new ArrayList<>();
|
||||||
|
for(AttachProvider provider : AttachProvider.providers()) {
|
||||||
|
for(VirtualMachineDescriptor vmd : provider.listVirtualMachines()) {
|
||||||
|
System.out.println("[" + vms.size() + "] " + vmd.id() + " " + vmd.displayName());
|
||||||
|
vms.add(vmd.id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BufferedReader(new InputStreamReader(System.in)).readLine();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ public class OpenJ9 {
|
|||||||
|
|
||||||
public static void heapdump() {
|
public static void heapdump() {
|
||||||
try {
|
try {
|
||||||
Dump.heapDumpToFile(new File(Main.jarPath.getParentFile(), "heap.phd").getPath());
|
Dump.heapDumpToFile(new File(System.getProperty("user.home"), "heap.phd").getPath());
|
||||||
} catch (InvalidDumpOptionException e) {
|
} catch (InvalidDumpOptionException e) {
|
||||||
Logger.getGlobal().log(Level.WARNING, "Could not perform heap dump", e);
|
Logger.getGlobal().log(Level.WARNING, "Could not perform heap dump", e);
|
||||||
}
|
}
|
||||||
|
@ -17,47 +17,50 @@ public class Sampler {
|
|||||||
waitingMethods.add("io.netty.channel.epoll.Native.epollWait");
|
waitingMethods.add("io.netty.channel.epoll.Native.epollWait");
|
||||||
waitingMethods.add("io.netty.channel.epoll.Native.epollWait0");
|
waitingMethods.add("io.netty.channel.epoll.Native.epollWait0");
|
||||||
waitingMethods.add("org.bukkit.craftbukkit.libs.jline.internal.NonBlockingInputStream.read");
|
waitingMethods.add("org.bukkit.craftbukkit.libs.jline.internal.NonBlockingInputStream.read");
|
||||||
waitingMethods.add("com.ibm.lang.management.internal.MemoryNotificationThread.processNotificationLoop");
|
|
||||||
waitingMethods.add("net.minecrell.terminalconsole.SimpleTerminalConsole.readCommands");
|
waitingMethods.add("net.minecrell.terminalconsole.SimpleTerminalConsole.readCommands");
|
||||||
waitingMethods.add("sun.nio.ch.SocketDispatcher.read0");
|
waitingMethods.add("com.ibm.lang.management.internal.MemoryNotificationThread.processNotificationLoop");
|
||||||
waitingMethods.add("openj9.internal.tools.attach.target.IPC.waitSemaphore");
|
waitingMethods.add("openj9.internal.tools.attach.target.IPC.waitSemaphore");
|
||||||
waitingMethods.add("sun.nio.ch.Net.poll");
|
waitingMethods.add("sun.nio.ch.Net.poll");
|
||||||
waitingMethods.add("java.lang.ProcessHandleImpl.waitForProcessExit0");
|
waitingMethods.add("sun.nio.ch.SocketDispatcher.read0");
|
||||||
waitingMethods.add("java.io.FileInputStream.readBytes");
|
|
||||||
waitingMethods.add("java.util.concurrent.locks.LockSupport.parkNanos");
|
|
||||||
waitingMethods.add("sun.awt.X11.XToolkit.waitForEvents");
|
waitingMethods.add("sun.awt.X11.XToolkit.waitForEvents");
|
||||||
|
waitingMethods.add("java.lang.ProcessHandleImpl.waitForProcessExit0");
|
||||||
waitingMethods.add("java.lang.ref.Reference.waitForReferencePendingList");
|
waitingMethods.add("java.lang.ref.Reference.waitForReferencePendingList");
|
||||||
|
waitingMethods.add("java.util.concurrent.locks.LockSupport.parkNanos");
|
||||||
|
waitingMethods.add("java.io.FileInputStream.readBytes");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final List<String> omittedMethods = new ArrayList<>();
|
private static final Set<String> omittedMethods = new HashSet<>();
|
||||||
static {
|
static {
|
||||||
omittedMethods.add("java.lang.reflect.Method.invoke");
|
omittedMethods.add("java.lang.reflect.Method.invoke");
|
||||||
omittedMethods.add("java.lang.Thread.run");
|
omittedMethods.add("java.lang.Thread.run");
|
||||||
omittedMethods.add("jdk.internal");
|
|
||||||
|
|
||||||
omittedMethods.add("java.util.stream");
|
|
||||||
omittedMethods.add("java.util.Iterator.forEachRemaining");
|
omittedMethods.add("java.util.Iterator.forEachRemaining");
|
||||||
omittedMethods.add("java.lang.Iterable.forEach");
|
omittedMethods.add("java.lang.Iterable.forEach");
|
||||||
|
omittedMethods.add("java.util.ArrayList.forEach");
|
||||||
|
omittedMethods.add("java.util.Map.forEach");
|
||||||
|
|
||||||
|
//TODO: Rework to concrete functions
|
||||||
|
omittedMethods.add("jdk.internal");
|
||||||
|
omittedMethods.add("java.util.stream");
|
||||||
omittedMethods.add("java.util.Spliterators");
|
omittedMethods.add("java.util.Spliterators");
|
||||||
omittedMethods.add("java.util.ArrayList$ArrayListSpliterator");
|
omittedMethods.add("java.util.ArrayList$ArrayListSpliterator");
|
||||||
omittedMethods.add("java.util.AbstractList$RandomAccessSpliterator");
|
omittedMethods.add("java.util.AbstractList$RandomAccessSpliterator");
|
||||||
omittedMethods.add("java.util.ArrayList.forEach");
|
|
||||||
omittedMethods.add("java.util.Map.forEach");
|
|
||||||
omittedMethods.add("java.util.concurrent");
|
omittedMethods.add("java.util.concurrent");
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<String, Trace> traces = new HashMap<>();
|
private final Map<String, Trace> traces = new HashMap<>();
|
||||||
private final Thread samplerThread;
|
private final Thread samplerThread;
|
||||||
private final boolean showDot;
|
private final Thread shutdownHook;
|
||||||
private boolean shutdown = false;
|
private boolean shutdown = false;
|
||||||
|
|
||||||
private int sampleRuns;
|
private int sampleRuns;
|
||||||
|
|
||||||
public Sampler(boolean showDot) {
|
public Sampler() {
|
||||||
this.showDot = showDot;
|
|
||||||
samplerThread = new Thread(this::run, "Sampler");
|
samplerThread = new Thread(this::run, "Sampler");
|
||||||
samplerThread.setDaemon(true);
|
samplerThread.setDaemon(true);
|
||||||
samplerThread.start();
|
samplerThread.start();
|
||||||
|
shutdownHook = new Thread(this::stop, "SamplerShutdownHook");
|
||||||
|
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSampleRuns() {
|
public int getSampleRuns() {
|
||||||
@ -72,14 +75,18 @@ public class Sampler {
|
|||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
File output = new File(Main.jarPath.getParentFile(), "samples.dot");
|
try {
|
||||||
|
Runtime.getRuntime().removeShutdownHook(shutdownHook);
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
//ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
File output = new File(System.getProperty("user.home"), "samples.dot");
|
||||||
try {
|
try {
|
||||||
OutputStreamWriter writer = new FileWriter(output);
|
OutputStreamWriter writer = new FileWriter(output);
|
||||||
toDot(writer);
|
toDot(writer);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
writer.close();
|
writer.close();
|
||||||
if(showDot)
|
|
||||||
new ProcessBuilder("xdot", "samples.dot").directory(Main.jarPath.getParentFile()).start();
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -137,7 +144,7 @@ public class Sampler {
|
|||||||
for(int i = stack.length - 1; i >= 0; i--) {
|
for(int i = stack.length - 1; i >= 0; i--) {
|
||||||
String id = ids[i];
|
String id = ids[i];
|
||||||
|
|
||||||
if(!previousIds.add(id) || omittedMethods.stream().anyMatch(id::startsWith))
|
if(!previousIds.add(id) || omittedMethods.contains(id))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Trace trace = traces.computeIfAbsent(id, id1 -> new Trace(this, id1));
|
Trace trace = traces.computeIfAbsent(id, id1 -> new Trace(this, id1));
|
||||||
|
@ -30,7 +30,7 @@ public class Trace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean filtered() {
|
private boolean filtered() {
|
||||||
return (samples[1] + samples[2]) / (double) sampler.getSampleRuns() < Sampler.FILTER;
|
return Arrays.stream(samples).sum() / (double) sampler.getSampleRuns() < Sampler.FILTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(Thread.State state, Trace predecessor) {
|
public void add(Thread.State state, Trace predecessor) {
|
||||||
|
5
steamwarci.yml
Normale Datei
5
steamwarci.yml
Normale Datei
@ -0,0 +1,5 @@
|
|||||||
|
build:
|
||||||
|
- "mvn package -B"
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
"/binarys/LixfelsProfiler.jar": "target/LixfelsProfiler.jar"
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren