aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/SamplerModule.java2
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java36
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/Sampler.java2
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/SamplerBuilder.java6
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/async/AsyncSampler.java10
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/java/JavaSampler.java12
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/sampler/java/TickedDataAggregator.java15
-rw-r--r--spark-common/src/main/proto/spark/spark_sampler.proto2
8 files changed, 64 insertions, 21 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 970d062..fd5cd67 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
@@ -266,7 +266,7 @@ public class SamplerModule implements CommandModule {
if (this.activeSampler == null) {
resp.replyPrefixed(text("There isn't an active profiler running."));
} else {
- long timeout = this.activeSampler.getEndTime();
+ long timeout = this.activeSampler.getAutoEndTime();
if (timeout == -1) {
resp.replyPrefixed(text("There is an active profiler currently running, with no defined timeout."));
} else {
diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java
index ce466a0..1c217db 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractSampler.java
@@ -27,6 +27,7 @@ import me.lucko.spark.common.platform.serverconfig.ServerConfigProvider;
import me.lucko.spark.common.sampler.aggregator.DataAggregator;
import me.lucko.spark.common.sampler.node.MergeMode;
import me.lucko.spark.common.sampler.node.ThreadNode;
+import me.lucko.spark.common.tick.TickHook;
import me.lucko.spark.common.util.ClassSourceLookup;
import me.lucko.spark.proto.SparkSamplerProtos.SamplerData;
import me.lucko.spark.proto.SparkSamplerProtos.SamplerMetadata;
@@ -41,6 +42,9 @@ import java.util.concurrent.CompletableFuture;
*/
public abstract class AbstractSampler implements Sampler {
+ /** The spark platform instance */
+ protected final SparkPlatform platform;
+
/** The interval to wait between sampling, in microseconds */
protected final int interval;
@@ -50,8 +54,11 @@ public abstract class AbstractSampler implements Sampler {
/** The time when sampling first began */
protected long startTime = -1;
+ /** The game tick when sampling first began */
+ protected int startTick = -1;
+
/** The unix timestamp (in millis) when this sampler should automatically complete. */
- protected final long endTime; // -1 for nothing
+ protected final long autoEndTime; // -1 for nothing
/** A future to encapsulate the completion of this sampler instance */
protected final CompletableFuture<Sampler> future = new CompletableFuture<>();
@@ -59,10 +66,11 @@ public abstract class AbstractSampler implements Sampler {
/** The garbage collector statistics when profiling started */
protected Map<String, GarbageCollectorStatistics> initialGcStats;
- protected AbstractSampler(int interval, ThreadDumper threadDumper, long endTime) {
+ protected AbstractSampler(SparkPlatform platform, int interval, ThreadDumper threadDumper, long autoEndTime) {
+ this.platform = platform;
this.interval = interval;
this.threadDumper = threadDumper;
- this.endTime = endTime;
+ this.autoEndTime = autoEndTime;
}
@Override
@@ -74,8 +82,8 @@ public abstract class AbstractSampler implements Sampler {
}
@Override
- public long getEndTime() {
- return this.endTime;
+ public long getAutoEndTime() {
+ return this.autoEndTime;
}
@Override
@@ -91,6 +99,16 @@ public abstract class AbstractSampler implements Sampler {
return this.initialGcStats;
}
+ @Override
+ public void start() {
+ this.startTime = System.currentTimeMillis();
+
+ TickHook tickHook = this.platform.getTickHook();
+ if (tickHook != null) {
+ this.startTick = tickHook.getCurrentTick();
+ }
+ }
+
protected void writeMetadataToProto(SamplerData.Builder proto, SparkPlatform platform, CommandSender creator, String comment, DataAggregator dataAggregator) {
SamplerMetadata.Builder metadata = SamplerMetadata.newBuilder()
.setPlatformMetadata(platform.getPlugin().getPlatformInfo().toData().toProto())
@@ -105,6 +123,14 @@ public abstract class AbstractSampler implements Sampler {
metadata.setComment(comment);
}
+ if (this.startTick != -1) {
+ TickHook tickHook = this.platform.getTickHook();
+ if (tickHook != null) {
+ int numberOfTicks = tickHook.getCurrentTick() - this.startTick;
+ metadata.setNumberOfTicks(numberOfTicks);
+ }
+ }
+
try {
metadata.setPlatformStatistics(platform.getStatisticsProvider().getPlatformStatistics(getInitialGcStats()));
} catch (Exception e) {
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 845043f..84f2da1 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
@@ -57,7 +57,7 @@ public interface Sampler {
*
* @return the end time, or -1 if undefined
*/
- long getEndTime();
+ long getAutoEndTime();
/**
* Gets a future to encapsulate the completion of the sampler
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 88cf018..88b9d91 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
@@ -97,11 +97,11 @@ public class SamplerBuilder {
Sampler sampler;
if (this.ticksOver != -1 && this.tickHook != null) {
- sampler = new JavaSampler(intervalMicros, this.threadDumper, this.threadGrouper, this.timeout, this.ignoreSleeping, this.ignoreNative, this.tickHook, this.ticksOver);
+ sampler = new JavaSampler(platform, intervalMicros, this.threadDumper, this.threadGrouper, this.timeout, this.ignoreSleeping, this.ignoreNative, this.tickHook, this.ticksOver);
} else if (this.useAsyncProfiler && !(this.threadDumper instanceof ThreadDumper.Regex) && AsyncProfilerAccess.INSTANCE.checkSupported(platform)) {
- sampler = new AsyncSampler(intervalMicros, this.threadDumper, this.threadGrouper, this.timeout);
+ sampler = new AsyncSampler(platform, intervalMicros, this.threadDumper, this.threadGrouper, this.timeout);
} else {
- sampler = new JavaSampler(intervalMicros, this.threadDumper, this.threadGrouper, this.timeout, this.ignoreSleeping, this.ignoreNative);
+ sampler = new JavaSampler(platform, intervalMicros, this.threadDumper, this.threadGrouper, this.timeout, this.ignoreSleeping, this.ignoreNative);
}
sampler.start();
diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/async/AsyncSampler.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/async/AsyncSampler.java
index 5cb7fdc..d8288da 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/sampler/async/AsyncSampler.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/async/AsyncSampler.java
@@ -65,8 +65,8 @@ public class AsyncSampler extends AbstractSampler {
/** The executor used for timeouts */
private ScheduledExecutorService timeoutExecutor;
- public AsyncSampler(int interval, ThreadDumper threadDumper, ThreadGrouper threadGrouper, long endTime) {
- super(interval, threadDumper, endTime);
+ public AsyncSampler(SparkPlatform platform, int interval, ThreadDumper threadDumper, ThreadGrouper threadGrouper, long endTime) {
+ super(platform, interval, threadDumper, endTime);
this.profiler = AsyncProfilerAccess.INSTANCE.getProfiler();
this.dataAggregator = new AsyncDataAggregator(threadGrouper);
}
@@ -90,7 +90,7 @@ public class AsyncSampler extends AbstractSampler {
*/
@Override
public void start() {
- this.startTime = System.currentTimeMillis();
+ super.start();
try {
this.outputFile = TemporaryFiles.create("spark-profile-", ".jfr.tmp");
@@ -120,11 +120,11 @@ public class AsyncSampler extends AbstractSampler {
}
private void scheduleTimeout() {
- if (this.endTime == -1) {
+ if (this.autoEndTime == -1) {
return;
}
- long delay = this.endTime - System.currentTimeMillis();
+ long delay = this.autoEndTime - System.currentTimeMillis();
if (delay <= 0) {
return;
}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/java/JavaSampler.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/java/JavaSampler.java
index cfa0a0f..913faee 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/sampler/java/JavaSampler.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/java/JavaSampler.java
@@ -63,19 +63,19 @@ public class JavaSampler extends AbstractSampler implements Runnable {
/** Responsible for aggregating and then outputting collected sampling data */
private final JavaDataAggregator dataAggregator;
- public JavaSampler(int interval, ThreadDumper threadDumper, ThreadGrouper threadGrouper, long endTime, boolean ignoreSleeping, boolean ignoreNative) {
- super(interval, threadDumper, endTime);
+ public JavaSampler(SparkPlatform platform, int interval, ThreadDumper threadDumper, ThreadGrouper threadGrouper, long endTime, boolean ignoreSleeping, boolean ignoreNative) {
+ super(platform, interval, threadDumper, endTime);
this.dataAggregator = new SimpleDataAggregator(this.workerPool, threadGrouper, interval, ignoreSleeping, ignoreNative);
}
- public JavaSampler(int interval, ThreadDumper threadDumper, ThreadGrouper threadGrouper, long endTime, boolean ignoreSleeping, boolean ignoreNative, TickHook tickHook, int tickLengthThreshold) {
- super(interval, threadDumper, endTime);
+ public JavaSampler(SparkPlatform platform, int interval, ThreadDumper threadDumper, ThreadGrouper threadGrouper, long endTime, boolean ignoreSleeping, boolean ignoreNative, TickHook tickHook, int tickLengthThreshold) {
+ super(platform, interval, threadDumper, endTime);
this.dataAggregator = new TickedDataAggregator(this.workerPool, threadGrouper, interval, ignoreSleeping, ignoreNative, tickHook, tickLengthThreshold);
}
@Override
public void start() {
- this.startTime = System.currentTimeMillis();
+ super.start();
this.task = this.workerPool.scheduleAtFixedRate(this, 0, this.interval, TimeUnit.MICROSECONDS);
}
@@ -89,7 +89,7 @@ public class JavaSampler extends AbstractSampler implements Runnable {
// this is effectively synchronized, the worker pool will not allow this task
// to concurrently execute.
try {
- if (this.endTime != -1 && this.endTime <= System.currentTimeMillis()) {
+ if (this.autoEndTime != -1 && this.autoEndTime <= System.currentTimeMillis()) {
this.future.complete(this);
stop();
return;
diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/java/TickedDataAggregator.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/java/TickedDataAggregator.java
index e817828..e062f31 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/sampler/java/TickedDataAggregator.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/java/TickedDataAggregator.java
@@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* Implementation of {@link DataAggregator} which supports only including sampling data from "ticks"
@@ -47,6 +48,9 @@ public class TickedDataAggregator extends JavaDataAggregator {
/** The expected number of samples in each tick */
private final int expectedSize;
+ /** The number of ticks aggregated so far */
+ private final AtomicInteger numberOfTicks = new AtomicInteger();
+
private final Object mutex = new Object();
// state
@@ -64,10 +68,16 @@ public class TickedDataAggregator extends JavaDataAggregator {
@Override
public SamplerMetadata.DataAggregator getMetadata() {
+ // push the current tick (so numberOfTicks is accurate)
+ synchronized (this.mutex) {
+ pushCurrentTick();
+ }
+
return SamplerMetadata.DataAggregator.newBuilder()
.setType(SamplerMetadata.DataAggregator.Type.TICKED)
.setThreadGrouper(this.threadGrouper.asProto())
.setTickLengthThreshold(this.tickLengthThreshold)
+ .setNumberOfIncludedTicks(this.numberOfTicks.get())
.build();
}
@@ -97,6 +107,7 @@ public class TickedDataAggregator extends JavaDataAggregator {
return;
}
+ this.numberOfTicks.incrementAndGet();
this.workerPool.submit(currentData);
}
@@ -110,6 +121,10 @@ public class TickedDataAggregator extends JavaDataAggregator {
return super.exportData();
}
+ public int getNumberOfTicks() {
+ return this.numberOfTicks.get();
+ }
+
private final class TickList implements Runnable {
private final List<ThreadInfo> list;
diff --git a/spark-common/src/main/proto/spark/spark_sampler.proto b/spark-common/src/main/proto/spark/spark_sampler.proto
index 51bdd64..8d9512a 100644
--- a/spark-common/src/main/proto/spark/spark_sampler.proto
+++ b/spark-common/src/main/proto/spark/spark_sampler.proto
@@ -25,6 +25,7 @@ message SamplerMetadata {
SystemStatistics system_statistics = 9;
map<string, string> server_configurations = 10;
int64 end_time = 11;
+ int32 number_of_ticks = 12;
message ThreadDumper {
Type type = 1;
@@ -42,6 +43,7 @@ message SamplerMetadata {
Type type = 1;
ThreadGrouper thread_grouper = 2;
int64 tick_length_threshold = 3; // optional
+ int32 number_of_included_ticks = 4; // optional
enum Type {
SIMPLE = 0;