hotspot/src/share/vm/services/memTracker.cpp
changeset 15452 3bfde2dea09d
parent 15104 f5d78994619f
child 16436 6b67e51e3cfb
equal deleted inserted replaced
15443:aa26996d55d6 15452:3bfde2dea09d
    27 #include "runtime/atomic.hpp"
    27 #include "runtime/atomic.hpp"
    28 #include "runtime/interfaceSupport.hpp"
    28 #include "runtime/interfaceSupport.hpp"
    29 #include "runtime/mutexLocker.hpp"
    29 #include "runtime/mutexLocker.hpp"
    30 #include "runtime/safepoint.hpp"
    30 #include "runtime/safepoint.hpp"
    31 #include "runtime/threadCritical.hpp"
    31 #include "runtime/threadCritical.hpp"
       
    32 #include "runtime/vm_operations.hpp"
    32 #include "services/memPtr.hpp"
    33 #include "services/memPtr.hpp"
    33 #include "services/memReporter.hpp"
    34 #include "services/memReporter.hpp"
    34 #include "services/memTracker.hpp"
    35 #include "services/memTracker.hpp"
    35 #include "utilities/decoder.hpp"
    36 #include "utilities/decoder.hpp"
    36 #include "utilities/globalDefinitions.hpp"
    37 #include "utilities/globalDefinitions.hpp"
    63 MemTracker::NMTLevel            MemTracker::_tracking_level = MemTracker::NMT_off;
    64 MemTracker::NMTLevel            MemTracker::_tracking_level = MemTracker::NMT_off;
    64 volatile MemTracker::NMTStates  MemTracker::_state = NMT_uninited;
    65 volatile MemTracker::NMTStates  MemTracker::_state = NMT_uninited;
    65 MemTracker::ShutdownReason      MemTracker::_reason = NMT_shutdown_none;
    66 MemTracker::ShutdownReason      MemTracker::_reason = NMT_shutdown_none;
    66 int                             MemTracker::_thread_count = 255;
    67 int                             MemTracker::_thread_count = 255;
    67 volatile jint                   MemTracker::_pooled_recorder_count = 0;
    68 volatile jint                   MemTracker::_pooled_recorder_count = 0;
       
    69 volatile unsigned long          MemTracker::_processing_generation = 0;
       
    70 volatile bool                   MemTracker::_worker_thread_idle = false;
    68 debug_only(intx                 MemTracker::_main_thread_tid = 0;)
    71 debug_only(intx                 MemTracker::_main_thread_tid = 0;)
    69 NOT_PRODUCT(volatile jint       MemTracker::_pending_recorder_count = 0;)
    72 NOT_PRODUCT(volatile jint       MemTracker::_pending_recorder_count = 0;)
    70 
    73 
    71 void MemTracker::init_tracking_options(const char* option_line) {
    74 void MemTracker::init_tracking_options(const char* option_line) {
    72   _tracking_level = NMT_off;
    75   _tracking_level = NMT_off;
   277        (void*)cur_head)) {
   280        (void*)cur_head)) {
   278        return get_new_or_pooled_instance();
   281        return get_new_or_pooled_instance();
   279      }
   282      }
   280      cur_head->set_next(NULL);
   283      cur_head->set_next(NULL);
   281      Atomic::dec(&_pooled_recorder_count);
   284      Atomic::dec(&_pooled_recorder_count);
   282      debug_only(cur_head->set_generation();)
   285      cur_head->set_generation();
   283      return cur_head;
   286      return cur_head;
   284   }
   287   }
   285 }
   288 }
   286 
   289 
   287 /*
   290 /*
   568     return true;
   571     return true;
   569   }
   572   }
   570   return false;
   573   return false;
   571 }
   574 }
   572 
   575 
       
   576 // Whitebox API for blocking until the current generation of NMT data has been merged
       
   577 bool MemTracker::wbtest_wait_for_data_merge() {
       
   578   // NMT can't be shutdown while we're holding _query_lock
       
   579   MutexLockerEx lock(_query_lock, true);
       
   580   assert(_worker_thread != NULL, "Invalid query");
       
   581   // the generation at query time, so NMT will spin till this generation is processed
       
   582   unsigned long generation_at_query_time = SequenceGenerator::current_generation();
       
   583   unsigned long current_processing_generation = _processing_generation;
       
   584   // if generation counter overflown
       
   585   bool generation_overflown = (generation_at_query_time < current_processing_generation);
       
   586   long generations_to_wrap = MAX_UNSIGNED_LONG - current_processing_generation;
       
   587   // spin
       
   588   while (!shutdown_in_progress()) {
       
   589     if (!generation_overflown) {
       
   590       if (current_processing_generation > generation_at_query_time) {
       
   591         return true;
       
   592       }
       
   593     } else {
       
   594       assert(generations_to_wrap >= 0, "Sanity check");
       
   595       long current_generations_to_wrap = MAX_UNSIGNED_LONG - current_processing_generation;
       
   596       assert(current_generations_to_wrap >= 0, "Sanity check");
       
   597       // to overflow an unsigned long should take long time, so to_wrap check should be sufficient
       
   598       if (current_generations_to_wrap > generations_to_wrap &&
       
   599           current_processing_generation > generation_at_query_time) {
       
   600         return true;
       
   601       }
       
   602     }
       
   603 
       
   604     // if worker thread is idle, but generation is not advancing, that means
       
   605     // there is not safepoint to let NMT advance generation, force one.
       
   606     if (_worker_thread_idle) {
       
   607       VM_ForceSafepoint vfs;
       
   608       VMThread::execute(&vfs);
       
   609     }
       
   610     MemSnapshot* snapshot = get_snapshot();
       
   611     if (snapshot == NULL) {
       
   612       return false;
       
   613     }
       
   614     snapshot->wait(1000);
       
   615     current_processing_generation = _processing_generation;
       
   616   }
       
   617   // We end up here if NMT is shutting down before our data has been merged
       
   618   return false;
       
   619 }
       
   620 
   573 // compare memory usage between current snapshot and baseline
   621 // compare memory usage between current snapshot and baseline
   574 bool MemTracker::compare_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
   622 bool MemTracker::compare_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
   575   MutexLockerEx lock(_query_lock, true);
   623   MutexLockerEx lock(_query_lock, true);
   576   if (_baseline.baselined()) {
   624   if (_baseline.baselined()) {
   577     MemBaseline baseline;
   625     MemBaseline baseline;