changeset 182:433e4bcd41ad

Bug 3250: Collect safepoint time when SnapShot is collected Summary: Add safepoint time into SnapShot Reviewed-by: ykubota https://github.com/HeapStats/heapstats/pull/61
author Yasumasa Suenaga <yasuenag@gmail.com>
date Mon, 12 Dec 2016 22:38:36 +0900
parents 42a918844ccd
children 64d1f518be76
files ChangeLog agent/src/heapstats-engines/classContainer.cpp agent/src/heapstats-engines/snapShotContainer.hpp analyzer/core/src/main/java/jp/co/ntt/oss/heapstats/container/snapshot/SnapShotHeader.java analyzer/core/src/main/java/jp/co/ntt/oss/heapstats/container/snapshot/SummaryData.java analyzer/core/src/main/java/jp/co/ntt/oss/heapstats/parser/SnapShotParser.java analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/SummaryController.java analyzer/fx/src/main/resources/snapshotResources_en.properties analyzer/fx/src/main/resources/snapshotResources_ja.properties
diffstat 9 files changed, 106 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Dec 12 22:29:55 2016 +0900
+++ b/ChangeLog	Mon Dec 12 22:38:36 2016 +0900
@@ -2,6 +2,7 @@
 
 	* Bug 3260: Cannot run FXAnalyzer via Maven task without NetBeans
 	* Bug 3261: Cannot start FXAnalyzer when HeapStatsFXAnalyzer.main() is called directly 
+	* Bug 3250: Collect safepoint time when SnapShot is collected
 
 2016-12-07  Yasumasa Suenaga <yasuenag@gmail.com>
 
--- a/agent/src/heapstats-engines/classContainer.cpp	Mon Dec 12 22:29:55 2016 +0900
+++ b/agent/src/heapstats-engines/classContainer.cpp	Mon Dec 12 22:38:36 2016 +0900
@@ -703,6 +703,10 @@
   memcpy(&hdr, (const void *)snapshot->getHeader(),
          sizeof(TSnapShotFileHeader));
 
+  /* Set safepoint time. */
+  hdr.safepointTime = jvmInfo->getSafepointTime();
+  hdr.magicNumber |= EXTENDED_SAFEPOINT_TIME;
+
   /* If java heap usage alert is enable. */
   if (conf->getHeapAlertThreshold() > 0) {
     jlong usage = hdr.newAreaSize + hdr.oldAreaSize;
--- a/agent/src/heapstats-engines/snapShotContainer.hpp	Mon Dec 12 22:29:55 2016 +0900
+++ b/agent/src/heapstats-engines/snapShotContainer.hpp	Mon Dec 12 22:38:36 2016 +0900
@@ -47,11 +47,13 @@
  *     0b10000000: This SnapShot is 2.0 format.
  *                 It contains snapshot and metaspace data.
  *     0b00000001: This SnapShot contains reference data.
- *       Other fields (bit 1 - 6) are reserved.
+ *     0b00000010: This SnapShot contains safepoint time.
+ *       Other fields (bit 2 - 6) are reserved.
  * \warning Don't change output snapshot format, if you change this value.
  */
 #define EXTENDED_SNAPSHOT         0x80  // 0b10000000
 #define EXTENDED_REFTREE_SNAPSHOT 0x81  // 0b10000001
+#define EXTENDED_SAFEPOINT_TIME   0x82  // 0b10000010
 
 /*!
  * \brief This structure stored class size and number of class-instance.
@@ -118,6 +120,7 @@
   jlong totalHeapSize;     /*!< Total heap size.                      */
   jlong metaspaceUsage;    /*!< Usage of PermGen or Metaspace.        */
   jlong metaspaceCapacity; /*!< Max capacity of PermGen or Metaspace. */
+  jlong safepointTime;     /*!< Safepoint time in milliseconds.       */
 } TSnapShotFileHeader;
 #pragma pack(pop)
 
--- a/analyzer/core/src/main/java/jp/co/ntt/oss/heapstats/container/snapshot/SnapShotHeader.java	Mon Dec 12 22:29:55 2016 +0900
+++ b/analyzer/core/src/main/java/jp/co/ntt/oss/heapstats/container/snapshot/SnapShotHeader.java	Mon Dec 12 22:38:36 2016 +0900
@@ -65,6 +65,11 @@
     public static final byte EXTENDED_FORMAT_FLAG_REFTREE = 0b00000001;
     
     /**
+     * Flag for safepoint time of extended SnapShot format.
+     */
+    public static final byte EXTENDED_FORMAT_FLAG_SAFEPOINT_TIME = 0b00000010;
+
+    /**
      * serialVersionUID.
      */
     static final long serialVersionUID = -539015033687122109L;
@@ -154,6 +159,11 @@
      */
     private long metaspaceCapacity;
 
+    /**
+     * Safepoint time.
+     */
+    private long safepointTime;
+
     private Path snapshotFile;
 
     private byte snapShotType;
@@ -183,6 +193,7 @@
         totalCapacity = 0;
         metaspaceUsage = 0;
         metaspaceCapacity = 0;
+        safepointTime = 0;
         snapShotCache = new SoftReference<>(null);
     }
 
@@ -465,6 +476,24 @@
     }
 
     /**
+     * Safepoint time.
+     *
+     * @return Return accumulated safepoint time
+     */
+    public final long getSafepointTime() {
+        return safepointTime;
+    }
+
+    /**
+     * Set safepoint time.
+     *
+     * @param value safepoint time
+     */
+    public final void setSafepointTime(final long value) {
+        safepointTime = value;
+    }
+
+    /**
      * Getter of SnapShot File.
      *
      * @return Path of this SnapShot.
@@ -609,6 +638,10 @@
                ((snapShotType & extended_reftree) == extended_reftree);
     }
 
+    public boolean hasSafepointTime(){
+        return (snapShotType & EXTENDED_FORMAT_FLAG_SAFEPOINT_TIME) == EXTENDED_FORMAT_FLAG_SAFEPOINT_TIME;
+    }
+
     public boolean hasMetaspaceData(){
         return (snapShotType != FILE_FORMAT_1_0);
     }
@@ -648,6 +681,9 @@
         buf.append(", Metaspace Capacity ");
         buf.append(metaspaceCapacity);
         buf.append(" byte ");
+        buf.append(", Accumulated safepoint time ");
+        buf.append(safepointTime);
+        buf.append(" ms");
 
         return buf.toString();
     }
--- a/analyzer/core/src/main/java/jp/co/ntt/oss/heapstats/container/snapshot/SummaryData.java	Mon Dec 12 22:29:55 2016 +0900
+++ b/analyzer/core/src/main/java/jp/co/ntt/oss/heapstats/container/snapshot/SummaryData.java	Mon Dec 12 22:38:36 2016 +0900
@@ -18,9 +18,11 @@
 package jp.co.ntt.oss.heapstats.container.snapshot;
 
 import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.OptionalInt;
+import java.util.stream.IntStream;
 
 /**
  * Summary data class.<br/>
@@ -78,6 +80,10 @@
 
     private final long maxEntryCount;
 
+    private final long safepointTime;
+
+    private final float safepointPercentage;
+
     private final List<LocalDateTime> rebootSuspectList;
 
     /**
@@ -124,6 +130,20 @@
         maxGCTime = statistics.getMaxGCTime();
         maxSnapshotSize = statistics.getMaxSnapshotSize();
         maxEntryCount = statistics.getMaxEntryCount();
+
+        boolean hasSafepointData = IntStream.range(lastRebootIndex.orElse(0), count)
+                                            .mapToObj(i -> headers.get(i))
+                                            .allMatch(h -> h.hasSafepointTime());
+        if(hasSafepointData){
+            safepointTime = end.getSafepointTime() - lastRebootStart.getSafepointTime();
+            long realTime = end.getSnapShotDate().toInstant(ZoneOffset.UTC).toEpochMilli() - lastRebootStart.getSnapShotDate().toInstant(ZoneOffset.UTC).toEpochMilli();
+            safepointPercentage = (float)safepointTime / (float)realTime * 100.0f;
+        }
+        else{
+            safepointTime = -1;
+            safepointPercentage = Float.NaN;
+        }
+
     }
 
     /**
@@ -190,6 +210,35 @@
     }
 
     /**
+     * Get accumulated safepoint time of this time range.
+     * If SnapShot headers has no safepoint time, this method returns -1.
+     *
+     * @return safepoint time
+     */
+    public long getSafepointTime() {
+        return safepointTime;
+    }
+
+    /**
+     * Get safepoint percentage of this time range.
+     * If SnapShot headers has no safepoint time, this method returns Float#NaN.
+     *
+     * @return safepoint percentage
+     */
+    public float getSafepointPercentage() {
+        return safepointPercentage;
+    }
+
+    /**
+     * This summary data has safepoint time.
+     * 
+     * @return true if this summary data has safepoint time.
+     */
+    public boolean hasSafepointTime(){
+        return safepointTime != -1;
+    }
+
+    /**
      * Get maximum value of SnapShot size.
      *
      * @return Maximum value of SnapShot size
--- a/analyzer/core/src/main/java/jp/co/ntt/oss/heapstats/parser/SnapShotParser.java	Mon Dec 12 22:29:55 2016 +0900
+++ b/analyzer/core/src/main/java/jp/co/ntt/oss/heapstats/parser/SnapShotParser.java	Mon Dec 12 22:38:36 2016 +0900
@@ -276,7 +276,12 @@
           // Metaspace capacity
           header.setMetaspaceCapacity(longBuffer.getLong());
         }
-        
+
+        if(header.hasSafepointTime()){
+            readLong(ch, 8);
+            header.setSafepointTime(longBuffer.getLong());
+        }
+
         header.setSnapShotHeaderSize(ch.position() - startPos);
 
         return header;
--- a/analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/SummaryController.java	Mon Dec 12 22:29:55 2016 +0900
+++ b/analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/SummaryController.java	Mon Dec 12 22:38:36 2016 +0900
@@ -116,12 +116,16 @@
             summaryTable.getItems().clear();
         } else {
             ResourceBundle resource = ResourceBundle.getBundle("snapshotResources", new Locale(HeapStatsUtils.getLanguage()));
+            String safepointTimeStr = data.hasSafepointTime() ? String.format("%d ms (%.02f %%)", data.getSafepointTime(), data.getSafepointPercentage())
+                                                              : "N/A";
+
             summaryTable.setItems(FXCollections.observableArrayList(new SummaryData.SummaryDataEntry(resource.getString("summary.snapshot.count"), Integer.toString(data.getCount())),
                     new SummaryData.SummaryDataEntry(resource.getString("summary.gc.count"), String.format("%d (Full: %d, Young: %d)", data.getFullCount() + data.getYngCount(), data.getFullCount(), data.getYngCount())),
                     new SummaryData.SummaryDataEntry(resource.getString("summary.heap.usage"), String.format("%.1f MB", data.getLatestHeapUsage() / 1024.0d / 1024.0d)),
                     new SummaryData.SummaryDataEntry(resource.getString("summary.metaspace.usage"), String.format("%.1f MB", data.getLatestMetaspaceUsage() / 1024.0d / 1024.0d)),
                     new SummaryData.SummaryDataEntry(resource.getString("summary.gc.time"), String.format("%d ms", data.getMaxGCTime())),
                     new SummaryData.SummaryDataEntry(resource.getString("summary.gc.totaltime"), String.format("%d ms", data.getTotalGCTime())),
+                    new SummaryData.SummaryDataEntry(resource.getString("summary.safepoint.time"), safepointTimeStr),
                     new SummaryData.SummaryDataEntry(resource.getString("summary.snapshot.size"), String.format("%.1f KB", data.getMaxSnapshotSize() / 1024.0d)),
                     new SummaryData.SummaryDataEntry(resource.getString("summary.snapshot.entrycount"), Long.toString(data.getMaxEntryCount()))
             ));
--- a/analyzer/fx/src/main/resources/snapshotResources_en.properties	Mon Dec 12 22:29:55 2016 +0900
+++ b/analyzer/fx/src/main/resources/snapshotResources_en.properties	Mon Dec 12 22:38:36 2016 +0900
@@ -42,6 +42,7 @@
 summary.gc.count = GC Count
 summary.gc.time = Max major GC time
 summary.gc.totaltime = Total major GC time
+summary.safepoint.time = Total safepoint time
 summary.heap.usage = Latest Java heap usage
 summary.metaspace.usage = Latest Metaspace usage
 
--- a/analyzer/fx/src/main/resources/snapshotResources_ja.properties	Mon Dec 12 22:29:55 2016 +0900
+++ b/analyzer/fx/src/main/resources/snapshotResources_ja.properties	Mon Dec 12 22:38:36 2016 +0900
@@ -42,6 +42,7 @@
 summary.gc.count = GC\u56de\u6570
 summary.gc.time = \u6700\u5927\u30e1\u30b8\u30e3\u30fcGC\u6642\u9593
 summary.gc.totaltime = \u7dcf\u30e1\u30b8\u30e3\u30fcGC\u6642\u9593
+summary.safepoint.time = \u7dcfSafepoint\u6642\u9593
 summary.heap.usage = \u6700\u7d42Java\u30d2\u30fc\u30d7\u4f7f\u7528\u91cf
 summary.metaspace.usage =\u6700\u7d42\u30e1\u30bf\u30b9\u30da\u30fc\u30b9\u4f7f\u7528\u91cf