Skip to content

Instantly share code, notes, and snippets.

@franz1981
Created September 18, 2018 15:50
Show Gist options
  • Save franz1981/3edc767ca3dacc92942e4d225f4cd3b4 to your computer and use it in GitHub Desktop.
Save franz1981/3edc767ca3dacc92942e4d225f4cd3b4 to your computer and use it in GitHub Desktop.
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.profile.GCProfiler;
import org.openjdk.jmh.profile.SafepointsProfiler;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.lang.management.ManagementFactory;
import java.util.concurrent.TimeUnit;
@State(Scope.Benchmark)
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(value = 3, jvmArgsAppend = {"-Xmx1g"})
public class TTSPBench {
//tune this to change the allocation rate (with <= G1GC)
private static final int WORKS = 100_000_000;
@GroupThreads(3)
@Group("test")
@Benchmark
public byte[] youngWillDieFirst() {
//16 bytes headers with compressedOops: 12 + 4
//1 cache line is 64 bytes -> it helps to not have fragmentations in regions
return new byte[64];
}
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
@Group("test")
@Benchmark
public long ttspDelayer() {
int limit = WORKS;
long k = 0;
for (int l = 0; l < limit; l++) {
k++;
if ((k % 2) == 1)
k += l;
}
return k;
//safepoint goes here if not inlined
}
@Group("test")
@Benchmark
public void safepointOperation() {
//the stack is not that deep: it will just trigger a safepoint
ManagementFactory.getThreadMXBean().dumpAllThreads(false, false);
}
public static void main(String[] args) throws RunnerException {
final Options opt = new OptionsBuilder()
.include(TTSPBench.class.getSimpleName())
//.jvmArgs("-XX:+UseShenandoahGC")
//.jvmArgs("-XX:+UnlockExperimentalVMOptions", "-XX:+UseZGC")
.addProfiler(GCProfiler.class)
.addProfiler(SafepointsProfiler.class)
.build();
new Runner(opt).run();
}
}
@nitsanw
Copy link

nitsanw commented Oct 11, 2018

This is an interesting "sensitivity to TTSP" measure though, which is thought provoking in itself.
I'm not sure it is a relevant comparison for concurrent GCs allocation rates capability though(as implied in your tweet IIRC). If a GC is concurrent, but has very short STW pauses or has to wait for all threads to pass a 'checkpoint' in order to make a transition(so mutators lock out the GC), they will suffer here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment