diff -r 3ba3f0e3f6c5 src/share/vm/runtime/thread.cpp
--- a/src/share/vm/runtime/thread.cpp	Tue Feb 25 10:34:33 2020 +0800
+++ b/src/share/vm/runtime/thread.cpp	Wed Sep 29 16:24:14 2021 +0300
@@ -3327,6 +3327,11 @@
   // Check version
   if (!is_supported_jni_version(args->version)) return JNI_EVERSION;
 
+  // Late initialization, still in single-threaded mode.
+  if (MemTracker::tracking_level() >= NMT_summary) {
+       MemTracker::init();
+   }
+
   // Initialize the output stream module
   ostream_init();
 
diff -r 3ba3f0e3f6c5 src/share/vm/services/memTracker.cpp
--- a/src/share/vm/services/memTracker.cpp	Tue Feb 25 10:34:33 2020 +0800
+++ b/src/share/vm/services/memTracker.cpp	Wed Sep 29 16:24:14 2021 +0300
@@ -85,10 +85,12 @@
       shutdown();
       return;
     }
-    _query_lock = new (std::nothrow) Mutex(Monitor::max_nonleaf, "NMT_queryLock");
-    // Already OOM. It is unlikely, but still have to handle it.
     if (_query_lock == NULL) {
-      shutdown();
+      _query_lock = new (std::nothrow) Mutex(Monitor::max_nonleaf, "NMT_queryLock");
+       // Already OOM. It is unlikely, but still have to handle it.
+      if (_query_lock == NULL) {
+        shutdown();
+      }
     }
   }
 }
diff -r 3ba3f0e3f6c5 src/share/vm/services/virtualMemoryTracker.cpp
--- a/src/share/vm/services/virtualMemoryTracker.cpp	Tue Feb 25 10:34:33 2020 +0800
+++ b/src/share/vm/services/virtualMemoryTracker.cpp	Wed Sep 29 16:24:14 2021 +0300
@@ -285,8 +285,11 @@
 
 bool VirtualMemoryTracker::late_initialize(NMT_TrackingLevel level) {
   if (level >= NMT_summary) {
-    _reserved_regions = new (std::nothrow, ResourceObj::C_HEAP, mtNMT)
-      SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>();
+    if (_reserved_regions == NULL) {
+      // Make sure we intialize it only once
+      _reserved_regions = new (std::nothrow, ResourceObj::C_HEAP, mtNMT)
+        SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>();
+    }
     return (_reserved_regions != NULL);
   }
   return true;
