Last active
January 29, 2022 05:36
-
-
Save jonatan-ivanov/0449619cb6f851ce67d70e47a6a1fb73 to your computer and use it in GitHub Desktop.
CPU Metrics Demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.example; | |
import java.lang.management.ManagementFactory; | |
import java.lang.management.OperatingSystemMXBean; | |
import java.time.Instant; | |
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.concurrent.ArrayBlockingQueue; | |
import java.util.concurrent.ExecutorService; | |
import java.util.concurrent.ForkJoinPool; | |
import java.util.concurrent.ThreadPoolExecutor; | |
import static java.util.concurrent.TimeUnit.SECONDS; | |
public class CpuMetricsDemo { | |
private static final int DURATION_SECONDS = 60; | |
public static void main(String[] args) throws InterruptedException { | |
generateLoad(4); | |
for (long i = 0; i < DURATION_SECONDS; i++) { | |
printInfo(); | |
Thread.sleep(1_000); | |
} | |
System.exit(0); | |
} | |
private static void printInfo() { | |
Map<String, Object> info = new HashMap<>(); | |
OperatingSystemMXBean osMXBean = ManagementFactory.getOperatingSystemMXBean(); | |
com.sun.management.OperatingSystemMXBean sunOsMXBean = (com.sun.management.OperatingSystemMXBean) osMXBean; // com.ibm.lang.management.OperatingSystemMXBean for OpenJ9 | |
System.out.println(Instant.now()); | |
// AvailableProcessors is very useful in containerized environments where the processor count may not match to the number of processors of the host. | |
// The JVM uses this value to size: | |
// - GC threads (and also choosing the GC: 1 processor -> SerialGC) | |
// - JIT Compiler threads | |
// - Common Pool (ForkJoin API, CompletableFuture, .stream().parallel()) | |
// see: https://docs.oracle.com/en/java/javase/17/gctuning/ergonomics.html | |
info.put("availableProcessors", Runtime.getRuntime().availableProcessors()); | |
info.put("commonPool.parallelism", ForkJoinPool.commonPool().getParallelism()); | |
// SystemLoadAverage shows you the average load for the last minute. | |
// This can be useful in containerized environments where the CPU resources might be limited so the avg load might be higher than the load you can see on the host. | |
// If you have 8 cores, and you put 4 of them under 100% load, the SystemLoadAverage should be around 4.0 (4 cores). | |
info.put("systemLoadAveragePerMinute", osMXBean.getSystemLoadAverage()); | |
// ProcessCpuTime shows you how much time does the CPU spend for executing instructions of the JVM. | |
// The return value is in nanos, but it is not necessarily nanosecond-accurate. | |
// If you run your process for 10 seconds, and you put 1 core under 100% load, the processCpuTime will be 10 seconds. | |
// If you run your process for 60 seconds, and you put 4 cores under 100% load, the processCpuTime will be 240 (4*60) seconds. | |
info.put("processCpuTime", sunOsMXBean.getProcessCpuTime()); | |
// SystemCpuLoad shows you "recent CPU usage" for the whole system. | |
// This can be useful in containerized environments where the CPU resources might be limited so the load might be higher than the load you can see on the host. | |
// The return value is a rate in the [0.0,1.0] interval: | |
// - 0.0 means that all CPUs were idle recently | |
// - 1.0 means that all CPUs were actively running 100% of the time recently | |
// - If you have 8 cores, and you put 4 cores under 100% load, systemCpuLoad will be around 0.5 | |
info.put("systemCpuLoad", sunOsMXBean.getSystemCpuLoad()); | |
// ProcessCpuLoad shows you "recent CPU usage" of the JVM. | |
// See systemCpuLoad for more details. | |
info.put("processCpuLoad", sunOsMXBean.getProcessCpuLoad()); | |
info.forEach((key, value) -> System.out.println("\t" + key + ":" + value)); | |
} | |
private static void generateLoad(int cpus) { | |
ExecutorService executor = new ThreadPoolExecutor(cpus, cpus, 0, SECONDS, new ArrayBlockingQueue<>(1)); | |
Runtime.getRuntime().addShutdownHook(new Thread(executor::shutdownNow)); | |
for (int i = 0; i < cpus; i++) { | |
executor.submit(CpuMetricsDemo::load); | |
} | |
} | |
private static void load() { | |
System.out.println(Thread.currentThread().getName() + " started"); | |
for (;;) { | |
if (Thread.currentThread().isInterrupted()) { | |
break; | |
} | |
} | |
System.out.println(Thread.currentThread().getName() + " stopped"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment