From 4e6364291746708297d753fbac24fbf27e19b65f Mon Sep 17 00:00:00 2001
Date: Thu, 14 May 2026 16:25:46 +0800
Subject: jcmd nmt add start time and end time

---
 src/hotspot/share/services/memReporter.cpp | 16 ++++++++++++++--
 src/hotspot/share/services/nmtDCmd.cpp     | 13 +++++++++++++
 src/hotspot/share/services/nmtDCmd.hpp     |  9 +++++++++
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/src/hotspot/share/services/memReporter.cpp b/src/hotspot/share/services/memReporter.cpp
index 07fb18aa5..1f87711b4 100644
--- a/src/hotspot/share/services/memReporter.cpp
+++ b/src/hotspot/share/services/memReporter.cpp
@@ -26,6 +26,7 @@
 #include "memory/allocation.hpp"
 #include "memory/metaspace.hpp"
 #include "memory/metaspaceUtils.hpp"
+#include "services/nmtDCmd.hpp"
 #include "services/mallocTracker.hpp"
 #include "services/memReporter.hpp"
 #include "services/threadStackTracker.hpp"
@@ -456,8 +457,19 @@ void MemDetailReporter::report_virtual_memory_region(const ReservedMemoryRegion*
 
 void MemSummaryDiffReporter::report_diff() {
   outputStream* out = output();
-  out->print_cr("\nNative Memory Tracking:\n");
-
+  time_t startTime = NMTDCmd::get_start_time();
+  time_t endTime = time(0);
+  struct tm endTimeTm = {0};
+  if (localtime_r(&endTime, &endTimeTm) == NULL) {
+    out->print_cr("\nNative Memory Tracking:\n");
+  } else {
+    out->print_cr("\nNative Memory Tracking: end time is %d-%02d-%02d %02d:%02d:%02d, elapsed time is %d secs\n",
+    static_cast<int>(endTimeTm.tm_year) + START_YEAR,
+    static_cast<int>(endTimeTm.tm_mon) + 1,
+    static_cast<int>(endTimeTm.tm_mday), static_cast<int>(endTimeTm.tm_hour),
+    static_cast<int>(endTimeTm.tm_min), static_cast<int>(endTimeTm.tm_sec),
+    static_cast<int>(endTime - startTime));
+  }
   if (scale() > 1) {
     out->print_cr("(Omitting categories weighting less than 1%s)", current_scale());
     out->cr();
diff --git a/src/hotspot/share/services/nmtDCmd.cpp b/src/hotspot/share/services/nmtDCmd.cpp
index d6f80613b..24c588988 100644
--- a/src/hotspot/share/services/nmtDCmd.cpp
+++ b/src/hotspot/share/services/nmtDCmd.cpp
@@ -69,6 +69,8 @@ size_t NMTDCmd::get_scale(const char* scale) const {
   return NMTUtil::scale_from_name(scale);
 }
 
+time_t NMTDCmd::_start_time = 0;
+
 void NMTDCmd::execute(DCmdSource source, TRAPS) {
   // Check NMT state
   //  native memory tracking has to be on
@@ -118,7 +120,18 @@ void NMTDCmd::execute(DCmdSource source, TRAPS) {
   } else if (_baseline.value()) {
     MemBaseline& baseline = MemTracker::get_baseline();
     baseline.baseline(MemTracker::tracking_level() != NMT_detail);
+    NMTDCmd::set_start_time(time(0));
+    time_t startTime = NMTDCmd::get_start_time();
+    struct tm startTimeTm = {0};
+    if (localtime_r(&startTime, &startTimeTm) == NULL) {
     output()->print_cr("Baseline taken");
+    } else {
+    output()->print_cr("Baseline taken, start time is %d-%02d-%02d %02d:%02d:%02d",
+    static_cast<int>(startTimeTm.tm_year) + START_YEAR,
+    static_cast<int>(startTimeTm.tm_mon) + 1,
+    static_cast<int>(startTimeTm.tm_mday), static_cast<int>(startTimeTm.tm_hour),
+    static_cast<int>(startTimeTm.tm_min), static_cast<int>(startTimeTm.tm_sec));
+    }
   } else if (_summary_diff.value()) {
     MemBaseline& baseline = MemTracker::get_baseline();
     if (baseline.baseline_type() >= MemBaseline::Summary_baselined) {
diff --git a/src/hotspot/share/services/nmtDCmd.hpp b/src/hotspot/share/services/nmtDCmd.hpp
index 9a06abb91..081c29ebe 100644
--- a/src/hotspot/share/services/nmtDCmd.hpp
+++ b/src/hotspot/share/services/nmtDCmd.hpp
@@ -30,6 +30,8 @@
 #include "services/memBaseline.hpp"
 #include "services/mallocTracker.hpp"
 
+const int START_YEAR = 1900; // tm struct, the number of years since 1900.
+
 /**
  * Native memory tracking DCmd implementation
  */
@@ -58,9 +60,16 @@ class NMTDCmd: public DCmdWithParser {
                         "monitor", nullptr};
     return p;
   }
+  static void set_start_time(const time_t &time) {
+    _start_time = time;
+  }
+  static time_t get_start_time() {
+    return _start_time;
+  }
   virtual void execute(DCmdSource source, TRAPS);
 
  private:
+  static time_t _start_time;
   void report(bool summaryOnly, size_t scale);
   void report_diff(bool summaryOnly, size_t scale);
 
-- 
2.17.1