diff --git a/core/src/main/java/com/yahoo/ycsb/Client.java b/core/src/main/java/com/yahoo/ycsb/Client.java index 0e0991189832847aed740944f31d167b885cde6a..de87be7c9b978a522b9ad9a6d7a8f86098cd3e4f 100644 --- a/core/src/main/java/com/yahoo/ycsb/Client.java +++ b/core/src/main/java/com/yahoo/ycsb/Client.java @@ -30,6 +30,7 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -696,10 +697,20 @@ public class Client double throughput = 1000.0 * (opcount) / (runtime); exporter.write("OVERALL", "Throughput(ops/sec)", throughput); - exporter.write("TOTAL_GCs", "Count", Utils.getGCTotalCollectionCount()); - final long gcTime = Utils.getGCTotalTime(); - exporter.write("TOTAL_GC_TIME", "Time(ms)", gcTime); - exporter.write("TOTAL_GC_TIME_%", "Time(%)", ((double)gcTime / runtime) * (double)100); + final Map<String, Long[]> gcs = Utils.getGCStatst(); + long totalGCCount = 0; + long totalGCTime = 0; + for (final Entry<String, Long[]> entry : gcs.entrySet()) { + exporter.write("TOTAL_GCS_" + entry.getKey(), "Count", entry.getValue()[0]); + exporter.write("TOTAL_GC_TIME_" + entry.getKey(), "Time(ms)", entry.getValue()[1]); + exporter.write("TOTAL_GC_TIME_%_" + entry.getKey(), "Time(%)",((double)entry.getValue()[1] / runtime) * (double)100); + totalGCCount += entry.getValue()[0]; + totalGCTime += entry.getValue()[1]; + } + exporter.write("TOTAL_GCs", "Count", totalGCCount); + + exporter.write("TOTAL_GC_TIME", "Time(ms)", totalGCTime); + exporter.write("TOTAL_GC_TIME_%", "Time(%)", ((double)totalGCTime / runtime) * (double)100); if (statusthread != null && statusthread.trackJVMStats()) { exporter.write("MAX_MEM_USED", "MBs", statusthread.getMaxUsedMem()); exporter.write("MIN_MEM_USED", "MBs", statusthread.getMinUsedMem()); diff --git a/core/src/main/java/com/yahoo/ycsb/Utils.java b/core/src/main/java/com/yahoo/ycsb/Utils.java index a6af3e173d7e6c210bd069b81bbf67ec22568cbe..05199fd7dd266ea09d9162df3c20369bd86f7d97 100644 --- a/core/src/main/java/com/yahoo/ycsb/Utils.java +++ b/core/src/main/java/com/yahoo/ycsb/Utils.java @@ -20,7 +20,9 @@ package com.yahoo.ycsb; import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Random; /** @@ -240,4 +242,32 @@ public class Utils } return time; } + + /** + * Returns a map of garbage collectors and their stats. + * The first object in the array is the total count since JVM start and the + * second is the total time (ms) since JVM start. + * If a garbage collectors does not support the collector MXBean, then it + * will not be represented in the map. + * @return A non-null map of garbage collectors and their metrics. The map + * may be empty. + */ + public static Map<String, Long[]> getGCStatst() { + final List<GarbageCollectorMXBean> gcBeans = + ManagementFactory.getGarbageCollectorMXBeans(); + final Map<String, Long[]> map = new HashMap<String, Long[]>(gcBeans.size()); + for (final GarbageCollectorMXBean bean : gcBeans) { + if (!bean.isValid() || bean.getCollectionCount() < 0 || + bean.getCollectionTime() < 0) { + continue; + } + + final Long[] measurements = new Long[] { + bean.getCollectionCount(), + bean.getCollectionTime() + }; + map.put(bean.getName().replace(" ", "_"), measurements); + } + return map; + } } diff --git a/core/src/test/java/com/yahoo/ycsb/TestUtils.java b/core/src/test/java/com/yahoo/ycsb/TestUtils.java index f9fddf7610503f5e3b64e533d67208b589b13b9e..a84eca86bbde9bea4a85f87770da0b034758f8a3 100644 --- a/core/src/test/java/com/yahoo/ycsb/TestUtils.java +++ b/core/src/test/java/com/yahoo/ycsb/TestUtils.java @@ -112,8 +112,10 @@ public class TestUtils { assertTrue(Utils.getGCTotalCollectionCount() >= 0); // Could be zero similar to GC total collection count assertTrue(Utils.getGCTotalTime() >= 0); + // Could be empty + assertTrue(Utils.getGCStatst().size() >= 0); } - + /** * Since this version of TestNG doesn't appear to have an assertArrayEquals, * this will compare the two to make sure they're the same.