diff options
author | Luck <git@lucko.me> | 2020-04-24 14:25:09 +0100 |
---|---|---|
committer | Luck <git@lucko.me> | 2020-04-24 14:25:09 +0100 |
commit | bdc2641e0997775f87fd413d9cb12716f0abd2f5 (patch) | |
tree | f437a19f313470e79960d927a333db724a7d956c /spark-common | |
parent | 88d39cfa0afd3b1388a5806396e9da7184abea49 (diff) | |
download | spark-bdc2641e0997775f87fd413d9cb12716f0abd2f5.tar.gz spark-bdc2641e0997775f87fd413d9cb12716f0abd2f5.tar.bz2 spark-bdc2641e0997775f87fd413d9cb12716f0abd2f5.zip |
Improve --ignore-sleeping flag, add --ignore-native flag
Diffstat (limited to 'spark-common')
6 files changed, 52 insertions, 14 deletions
diff --git a/spark-common/src/main/java/me/lucko/spark/common/command/modules/SamplerModule.java b/spark-common/src/main/java/me/lucko/spark/common/command/modules/SamplerModule.java index b2b7a16..b8d8cc6 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/command/modules/SamplerModule.java +++ b/spark-common/src/main/java/me/lucko/spark/common/command/modules/SamplerModule.java @@ -81,6 +81,7 @@ public class SamplerModule implements CommandModule { .argumentUsage("interval", "interval millis") .argumentUsage("only-ticks-over", "tick length millis") .argumentUsage("ignore-sleeping", null) + .argumentUsage("ignore-native", null) .argumentUsage("order-by-time", null) .argumentUsage("separate-parent-calls", null) .executor((platform, sender, resp, arguments) -> { @@ -146,6 +147,7 @@ public class SamplerModule implements CommandModule { } boolean ignoreSleeping = arguments.boolFlag("ignore-sleeping"); + boolean ignoreNative = arguments.boolFlag("ignore-native"); Set<String> threads = arguments.stringFlag("thread"); ThreadDumper threadDumper; @@ -197,6 +199,7 @@ public class SamplerModule implements CommandModule { } builder.samplingInterval(intervalMillis); builder.ignoreSleeping(ignoreSleeping); + builder.ignoreNative(ignoreNative); if (ticksOver != -1) { builder.ticksOver(ticksOver, tickHook); } @@ -249,7 +252,8 @@ public class SamplerModule implements CommandModule { List<String> opts = new ArrayList<>(Arrays.asList("--info", "--stop", "--cancel", "--timeout", "--regex", "--combine-all", "--not-combined", "--interval", - "--only-ticks-over", "--ignore-sleeping", "--order-by-time", "--separate-parent-calls", "--comment")); + "--only-ticks-over", "--ignore-sleeping", "--ignore-native", "--order-by-time", + "--separate-parent-calls", "--comment")); opts.removeAll(arguments); opts.add("--thread"); // allowed multiple times diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/Sampler.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/Sampler.java index ec01da2..63383b4 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/Sampler.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/Sampler.java @@ -22,7 +22,6 @@ package me.lucko.spark.common.sampler; import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.google.protobuf.ByteString; import me.lucko.spark.common.command.sender.CommandSender; import me.lucko.spark.common.sampler.aggregator.DataAggregator; import me.lucko.spark.common.sampler.aggregator.SimpleDataAggregator; @@ -82,16 +81,16 @@ public class Sampler implements Runnable { /** The unix timestamp (in millis) when this sampler should automatically complete.*/ private final long endTime; // -1 for nothing - public Sampler(int interval, ThreadDumper threadDumper, ThreadGrouper threadGrouper, long endTime, boolean ignoreSleeping) { + public Sampler(int interval, ThreadDumper threadDumper, ThreadGrouper threadGrouper, long endTime, boolean ignoreSleeping, boolean ignoreNative) { this.threadDumper = threadDumper; - this.dataAggregator = new SimpleDataAggregator(this.workerPool, threadGrouper, interval, ignoreSleeping); + this.dataAggregator = new SimpleDataAggregator(this.workerPool, threadGrouper, interval, ignoreSleeping, ignoreNative); this.interval = interval; this.endTime = endTime; } - public Sampler(int interval, ThreadDumper threadDumper, ThreadGrouper threadGrouper, long endTime, boolean ignoreSleeping, TickHook tickHook, int tickLengthThreshold) { + public Sampler(int interval, ThreadDumper threadDumper, ThreadGrouper threadGrouper, long endTime, boolean ignoreSleeping, boolean ignoreNative, TickHook tickHook, int tickLengthThreshold) { this.threadDumper = threadDumper; - this.dataAggregator = new TickedDataAggregator(this.workerPool, threadGrouper, interval, ignoreSleeping, tickHook, tickLengthThreshold); + this.dataAggregator = new TickedDataAggregator(this.workerPool, threadGrouper, interval, ignoreSleeping, ignoreNative, tickHook, tickLengthThreshold); this.interval = interval; this.endTime = endTime; } diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/SamplerBuilder.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/SamplerBuilder.java index ff4c6df..8993445 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/SamplerBuilder.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/SamplerBuilder.java @@ -31,6 +31,7 @@ public class SamplerBuilder { private double samplingInterval = 4; // milliseconds private boolean ignoreSleeping = false; + private boolean ignoreNative = false; private long timeout = -1; private ThreadDumper threadDumper = ThreadDumper.ALL; private ThreadGrouper threadGrouper = ThreadGrouper.BY_NAME; @@ -75,14 +76,19 @@ public class SamplerBuilder { return this; } + public SamplerBuilder ignoreNative(boolean ignoreNative) { + this.ignoreNative = ignoreNative; + return this; + } + public Sampler start() { Sampler sampler; int intervalMicros = (int) (this.samplingInterval * 1000d); if (this.ticksOver == -1 || this.tickHook == null) { - sampler = new Sampler(intervalMicros, this.threadDumper, this.threadGrouper, this.timeout, this.ignoreSleeping); + sampler = new Sampler(intervalMicros, this.threadDumper, this.threadGrouper, this.timeout, this.ignoreSleeping, this.ignoreNative); } else { - sampler = new Sampler(intervalMicros, this.threadDumper, this.threadGrouper, this.timeout, this.ignoreSleeping, this.tickHook, this.ticksOver); + sampler = new Sampler(intervalMicros, this.threadDumper, this.threadGrouper, this.timeout, this.ignoreSleeping, this.ignoreNative, this.tickHook, this.ticksOver); } sampler.start(); diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/AbstractDataAggregator.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/AbstractDataAggregator.java index 8b401cc..c9a4f37 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/AbstractDataAggregator.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/AbstractDataAggregator.java @@ -45,11 +45,15 @@ public abstract class AbstractDataAggregator implements DataAggregator { /** If sleeping threads should be ignored */ private final boolean ignoreSleeping; - public AbstractDataAggregator(ExecutorService workerPool, ThreadGrouper threadGrouper, int interval, boolean ignoreSleeping) { + /** If threads executing native code should be ignored */ + private final boolean ignoreNative; + + public AbstractDataAggregator(ExecutorService workerPool, ThreadGrouper threadGrouper, int interval, boolean ignoreSleeping, boolean ignoreNative) { this.workerPool = workerPool; this.threadGrouper = threadGrouper; this.interval = interval; this.ignoreSleeping = ignoreSleeping; + this.ignoreNative = ignoreNative; } protected ThreadNode getNode(String group) { @@ -61,7 +65,10 @@ public abstract class AbstractDataAggregator implements DataAggregator { } protected void writeData(ThreadInfo threadInfo) { - if (this.ignoreSleeping && (threadInfo.getThreadState() == Thread.State.WAITING || threadInfo.getThreadState() == Thread.State.TIMED_WAITING)) { + if (this.ignoreSleeping && isSleeping(threadInfo)) { + return; + } + if (this.ignoreNative && threadInfo.isInNative()) { return; } @@ -73,4 +80,26 @@ public abstract class AbstractDataAggregator implements DataAggregator { } } + private static boolean isSleeping(ThreadInfo thread) { + if (thread.getThreadState() == Thread.State.WAITING || thread.getThreadState() == Thread.State.TIMED_WAITING) { + return true; + } + + StackTraceElement[] stackTrace = thread.getStackTrace(); + if (stackTrace.length == 0) { + return false; + } + + StackTraceElement call = stackTrace[0]; + String clazz = call.getClassName(); + String method = call.getMethodName(); + + // java.lang.Thread.yield() + // jdk.internal.misc.Unsafe.park() + // sun.misc.Unsafe.park() + return (clazz.equals("java.lang.Thread") && method.equals("yield")) || + (clazz.equals("jdk.internal.misc.Unsafe") && method.equals("park")) || + (clazz.equals("sun.misc.Unsafe") && method.equals("park")); + } + } diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/SimpleDataAggregator.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/SimpleDataAggregator.java index 4272ccd..8463f98 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/SimpleDataAggregator.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/SimpleDataAggregator.java @@ -33,8 +33,8 @@ import java.util.concurrent.TimeUnit; * Basic implementation of {@link DataAggregator}. */ public class SimpleDataAggregator extends AbstractDataAggregator { - public SimpleDataAggregator(ExecutorService workerPool, ThreadGrouper threadGrouper, int interval, boolean ignoreSleeping) { - super(workerPool, threadGrouper, interval, ignoreSleeping); + public SimpleDataAggregator(ExecutorService workerPool, ThreadGrouper threadGrouper, int interval, boolean ignoreSleeping, boolean ignoreNative) { + super(workerPool, threadGrouper, interval, ignoreSleeping, ignoreNative); } @Override diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/TickedDataAggregator.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/TickedDataAggregator.java index b5a8aad..7ad6781 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/TickedDataAggregator.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/TickedDataAggregator.java @@ -53,8 +53,8 @@ public class TickedDataAggregator extends AbstractDataAggregator { private int currentTick = -1; private TickList currentData = new TickList(0); - public TickedDataAggregator(ExecutorService workerPool, ThreadGrouper threadGrouper, int interval, boolean ignoreSleeping, TickHook tickHook, int tickLengthThreshold) { - super(workerPool, threadGrouper, interval, ignoreSleeping); + public TickedDataAggregator(ExecutorService workerPool, ThreadGrouper threadGrouper, int interval, boolean ignoreSleeping, boolean ignoreNative, TickHook tickHook, int tickLengthThreshold) { + super(workerPool, threadGrouper, interval, ignoreSleeping, ignoreNative); this.tickHook = tickHook; this.tickLengthThreshold = TimeUnit.MILLISECONDS.toMicros(tickLengthThreshold); // 50 millis in a tick, plus 10 so we have a bit of room to go over |