Java 27 and 26: runnable demos and captured output for every JEP, plus version lanes
Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B38FGKKam5SCGgwgduVAh3
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import java.lang.management.GarbageCollectorMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* A deliberately boring allocation workload, used to ask one question: what does the switch from
|
||||
* Serial to G1 cost (or save) on a machine that used to get Serial?
|
||||
*
|
||||
* <p>It allocates small objects as fast as it can, keeps roughly 1% of them alive in a ring buffer
|
||||
* (so the collector has real work to do, not just an empty young generation), and reports wall
|
||||
* time, collection count and time, the slowest single batch (a rough stand-in for the worst
|
||||
* stall an application thread saw), and the process's peak resident memory from /proc.
|
||||
*
|
||||
* <p>Timing numbers are indicative, not a benchmark: one process, one run, a shared machine.
|
||||
* The point is the SHAPE of the difference. See docs/02-g1-default.md.
|
||||
*/
|
||||
public class Workload {
|
||||
|
||||
record Item(long id, String label, byte[] payload) {}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
int batches = args.length > 0 ? Integer.parseInt(args[0]) : 400;
|
||||
int perBatch = 50_000;
|
||||
Item[] ring = new Item[100_000];
|
||||
int ringPos = 0;
|
||||
long checksum = 0;
|
||||
long slowestBatchNanos = 0;
|
||||
|
||||
long start = System.nanoTime();
|
||||
for (int b = 0; b < batches; b++) {
|
||||
long t0 = System.nanoTime();
|
||||
for (int i = 0; i < perBatch; i++) {
|
||||
long id = (long) b * perBatch + i;
|
||||
Item item = new Item(id, "item-" + id, new byte[64 + (int) (id & 63)]);
|
||||
checksum += item.payload().length;
|
||||
if (id % 100 == 0) {
|
||||
ring[ringPos] = item;
|
||||
ringPos = (ringPos + 1) % ring.length;
|
||||
}
|
||||
}
|
||||
slowestBatchNanos = Math.max(slowestBatchNanos, System.nanoTime() - t0);
|
||||
}
|
||||
long elapsedMs = (System.nanoTime() - start) / 1_000_000;
|
||||
|
||||
long gcCount = 0, gcMs = 0;
|
||||
for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
|
||||
gcCount += Math.max(0, gc.getCollectionCount());
|
||||
gcMs += Math.max(0, gc.getCollectionTime());
|
||||
}
|
||||
System.out.printf("allocated objects = %,d (checksum %d)%n", (long) batches * perBatch, checksum);
|
||||
System.out.printf("wall time = %d ms%n", elapsedMs);
|
||||
System.out.printf("gc count / time = %d / %d ms%n", gcCount, gcMs);
|
||||
System.out.printf("slowest batch = %d ms%n", slowestBatchNanos / 1_000_000);
|
||||
System.out.printf("peak RSS = %d MB%n", peakRssKb() / 1024);
|
||||
}
|
||||
|
||||
/** VmHWM is the high-water mark of the resident set, in kB. */
|
||||
static long peakRssKb() throws Exception {
|
||||
for (String line : Files.readAllLines(Path.of("/proc/self/status"))) {
|
||||
if (line.startsWith("VmHWM:")) {
|
||||
return Long.parseLong(line.replaceAll("\\D+", ""));
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user