Sometimes it is useful to see what the Java Virtual Machine (JVM) is doing when it is running your program. In this blog we will see how to get metrics about memory, buffers, threads and the garbage collection (gc) process from the JVM. The metrics-core and the metrics-jvm package from Codahale is all we need. We start with the MetricRegistry:
final MetricRegistry registry = new MetricRegistry();
Then we create a helper method that registers all metrics in a MetricSet:
private void registerAll(String prefix, MetricSet metricSet, MetricRegistry registry) { for (Entry<String, Metric> entry : metricSet.getMetrics().entrySet()) { if (entry.getValue() instanceof MetricSet) { registerAll(prefix + "." + entry.getKey(), (MetricSet) entry.getValue(), registry); } else { registry.register(prefix + "." + entry.getKey(), entry.getValue()); } } }
Then we register all four metric sets:
registerAll("gc", new GarbageCollectorMetricSet(), registry); registerAll("buffers", new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()), registry); registerAll("memory", new MemoryUsageGaugeSet(), registry); registerAll("threads", new ThreadStatesGaugeSet(), registry);
And then we are able to loop through all metrics and print their values:
private void printAllMetrics() { for (String metricName : registry.getGauges().keySet()) { printMetric(metricName); } } private void printMetric(String metricName) { Object value = registry.getGauges().get(metricName).getValue(); System.out.println("name=" + metricName + ", value=" + value); }
As a final test, we show only the value of a single metric, memory.heap.usage, create a big byte array and then show the value again:
printMetric("memory.heap.usage"); byte[] big = new byte[1000000000]; printMetric("memory.heap.usage");
This outputs something like this:
name=memory.heap.usage, value=0.003236333145280586 name=memory.heap.usage, value=0.5296919399159342
Getting metrics from the Java Virtual Machine (JVM)