< prev index next >

src/hotspot/share/services/threadService.cpp

Print this page




  40 #include "runtime/vframe.hpp"
  41 #include "runtime/vmThread.hpp"
  42 #include "runtime/vm_operations.hpp"
  43 #include "services/threadService.hpp"
  44 
  45 // TODO: we need to define a naming convention for perf counters
  46 // to distinguish counters for:
  47 //   - standard JSR174 use
  48 //   - Hotspot extension (public and committed)
  49 //   - Hotspot extension (private/internal and uncommitted)
  50 
  51 // Default is disabled.
  52 bool ThreadService::_thread_monitoring_contention_enabled = false;
  53 bool ThreadService::_thread_cpu_time_enabled = false;
  54 bool ThreadService::_thread_allocated_memory_enabled = false;
  55 
  56 PerfCounter*  ThreadService::_total_threads_count = NULL;
  57 PerfVariable* ThreadService::_live_threads_count = NULL;
  58 PerfVariable* ThreadService::_peak_threads_count = NULL;
  59 PerfVariable* ThreadService::_daemon_threads_count = NULL;
  60 volatile int ThreadService::_exiting_threads_count = 0;
  61 volatile int ThreadService::_exiting_daemon_threads_count = 0;
  62 
  63 ThreadDumpResult* ThreadService::_threaddump_list = NULL;
  64 
  65 static const int INITIAL_ARRAY_SIZE = 10;
  66 
  67 void ThreadService::init() {
  68   EXCEPTION_MARK;
  69 
  70   // These counters are for java.lang.management API support.
  71   // They are created even if -XX:-UsePerfData is set and in
  72   // that case, they will be allocated on C heap.
  73 
  74   _total_threads_count =
  75                 PerfDataManager::create_counter(JAVA_THREADS, "started",
  76                                                 PerfData::U_Events, CHECK);
  77 
  78   _live_threads_count =
  79                 PerfDataManager::create_variable(JAVA_THREADS, "live",
  80                                                  PerfData::U_None, CHECK);
  81 


  84                                                  PerfData::U_None, CHECK);
  85 
  86   _daemon_threads_count =
  87                 PerfDataManager::create_variable(JAVA_THREADS, "daemon",
  88                                                  PerfData::U_None, CHECK);
  89 
  90   if (os::is_thread_cpu_time_supported()) {
  91     _thread_cpu_time_enabled = true;
  92   }
  93 
  94   _thread_allocated_memory_enabled = true; // Always on, so enable it
  95 }
  96 
  97 void ThreadService::reset_peak_thread_count() {
  98   // Acquire the lock to update the peak thread count
  99   // to synchronize with thread addition and removal.
 100   MutexLockerEx mu(Threads_lock);
 101   _peak_threads_count->set_value(get_live_thread_count());
 102 }
 103 




 104 void ThreadService::add_thread(JavaThread* thread, bool daemon) {


 105   // Do not count VM internal or JVMTI agent threads
 106   if (thread->is_hidden_from_external_view() ||
 107       thread->is_jvmti_agent_thread()) {
 108     return;
 109   }
 110 
 111   _total_threads_count->inc();
 112   _live_threads_count->inc();


 113 
 114   if (_live_threads_count->get_value() > _peak_threads_count->get_value()) {
 115     _peak_threads_count->set_value(_live_threads_count->get_value());
 116   }
 117 
 118   if (daemon) {
 119     _daemon_threads_count->inc();

 120   }
 121 }
 122 
 123 void ThreadService::remove_thread(JavaThread* thread, bool daemon) {
 124   Atomic::dec(&_exiting_threads_count);
 125   if (daemon) {
 126     Atomic::dec(&_exiting_daemon_threads_count);


 127   }




 128 
 129   if (thread->is_hidden_from_external_view() ||
 130       thread->is_jvmti_agent_thread()) {
 131     return;
 132   }
 133 
 134   _live_threads_count->set_value(_live_threads_count->get_value() - 1);















 135   if (daemon) {
 136     _daemon_threads_count->set_value(_daemon_threads_count->get_value() - 1);
 137   }























 138 }
 139 
 140 void ThreadService::current_thread_exiting(JavaThread* jt) {





 141   assert(jt == JavaThread::current(), "Called by current thread");
 142   Atomic::inc(&_exiting_threads_count);
 143 
 144   oop threadObj = jt->threadObj();
 145   if (threadObj != NULL && java_lang_Thread::is_daemon(threadObj)) {
 146     Atomic::inc(&_exiting_daemon_threads_count);
 147   }
 148 }
 149 
 150 // FIXME: JVMTI should call this function
 151 Handle ThreadService::get_current_contended_monitor(JavaThread* thread) {
 152   assert(thread != NULL, "should be non-NULL");
 153   debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 154 
 155   ObjectMonitor *wait_obj = thread->current_waiting_monitor();
 156 
 157   oop obj = NULL;
 158   if (wait_obj != NULL) {
 159     // thread is doing an Object.wait() call
 160     obj = (oop) wait_obj->object();
 161     assert(obj != NULL, "Object.wait() should have an object");
 162   } else {
 163     ObjectMonitor *enter_obj = thread->current_pending_monitor();
 164     if (enter_obj != NULL) {
 165       // thread is trying to enter() or raw_enter() an ObjectMonitor.
 166       obj = (oop) enter_obj->object();
 167     }




  40 #include "runtime/vframe.hpp"
  41 #include "runtime/vmThread.hpp"
  42 #include "runtime/vm_operations.hpp"
  43 #include "services/threadService.hpp"
  44 
  45 // TODO: we need to define a naming convention for perf counters
  46 // to distinguish counters for:
  47 //   - standard JSR174 use
  48 //   - Hotspot extension (public and committed)
  49 //   - Hotspot extension (private/internal and uncommitted)
  50 
  51 // Default is disabled.
  52 bool ThreadService::_thread_monitoring_contention_enabled = false;
  53 bool ThreadService::_thread_cpu_time_enabled = false;
  54 bool ThreadService::_thread_allocated_memory_enabled = false;
  55 
  56 PerfCounter*  ThreadService::_total_threads_count = NULL;
  57 PerfVariable* ThreadService::_live_threads_count = NULL;
  58 PerfVariable* ThreadService::_peak_threads_count = NULL;
  59 PerfVariable* ThreadService::_daemon_threads_count = NULL;
  60 volatile int ThreadService::_atomic_threads_count = 0;
  61 volatile int ThreadService::_atomic_daemon_threads_count = 0;
  62 
  63 ThreadDumpResult* ThreadService::_threaddump_list = NULL;
  64 
  65 static const int INITIAL_ARRAY_SIZE = 10;
  66 
  67 void ThreadService::init() {
  68   EXCEPTION_MARK;
  69 
  70   // These counters are for java.lang.management API support.
  71   // They are created even if -XX:-UsePerfData is set and in
  72   // that case, they will be allocated on C heap.
  73 
  74   _total_threads_count =
  75                 PerfDataManager::create_counter(JAVA_THREADS, "started",
  76                                                 PerfData::U_Events, CHECK);
  77 
  78   _live_threads_count =
  79                 PerfDataManager::create_variable(JAVA_THREADS, "live",
  80                                                  PerfData::U_None, CHECK);
  81 


  84                                                  PerfData::U_None, CHECK);
  85 
  86   _daemon_threads_count =
  87                 PerfDataManager::create_variable(JAVA_THREADS, "daemon",
  88                                                  PerfData::U_None, CHECK);
  89 
  90   if (os::is_thread_cpu_time_supported()) {
  91     _thread_cpu_time_enabled = true;
  92   }
  93 
  94   _thread_allocated_memory_enabled = true; // Always on, so enable it
  95 }
  96 
  97 void ThreadService::reset_peak_thread_count() {
  98   // Acquire the lock to update the peak thread count
  99   // to synchronize with thread addition and removal.
 100   MutexLockerEx mu(Threads_lock);
 101   _peak_threads_count->set_value(get_live_thread_count());
 102 }
 103 
 104 static bool is_hidden_thread(JavaThread *thread) {
 105   return thread->is_hidden_from_external_view() || thread->is_jvmti_agent_thread();
 106 }
 107 
 108 void ThreadService::add_thread(JavaThread* thread, bool daemon) {
 109   assert(Threads_lock->owned_by_self(), "must have threads lock");
 110 
 111   // Do not count VM internal or JVMTI agent threads
 112   if (is_hidden_thread(thread)) {

 113     return;
 114   }
 115 
 116   _total_threads_count->inc();
 117   _live_threads_count->inc();
 118   Atomic::inc(&_atomic_threads_count);
 119   int count = _atomic_threads_count;
 120 
 121   if (count > _peak_threads_count->get_value()) {
 122     _peak_threads_count->set_value(count);
 123   }
 124 
 125   if (daemon) {
 126     _daemon_threads_count->inc();
 127     Atomic::inc(&_atomic_daemon_threads_count);
 128   }
 129 }
 130 
 131 void ThreadService::decrement_thread_counts(JavaThread* jt) {
 132   Atomic::dec(&_atomic_threads_count);
 133 
 134   oop threadObj = jt->threadObj();
 135   if (threadObj != NULL && java_lang_Thread::is_daemon(threadObj)) {
 136     Atomic::dec(&_atomic_daemon_threads_count);
 137   }
 138 }
 139 
 140 void ThreadService::remove_thread(JavaThread* thread, bool daemon) {
 141   assert(Threads_lock->owned_by_self(), "must have threads lock");
 142 
 143   // Do not count VM internal or JVMTI agent threads
 144   if (is_hidden_thread(thread)) {
 145     return;
 146   }
 147 
 148   assert(!thread->is_terminated(), "must not be terminated");
 149   if (!thread->is_exiting()) {
 150     // JavaThread::exit() skipped calling current_thread_exiting()
 151     decrement_thread_counts(thread);
 152   }
 153 
 154   int daemon_count = _atomic_daemon_threads_count;
 155   int count = _atomic_threads_count;
 156 
 157   // Counts are incremented at the same time, but atomic counts are
 158   // decremented earlier than perf counts.
 159   assert(_live_threads_count->get_value() > count,
 160     "thread count mismatch %d : %d",
 161     (int)_live_threads_count->get_value(), count);
 162 
 163   _live_threads_count->dec(1);
 164   if (daemon) {
 165     assert(_daemon_threads_count->get_value() > daemon_count,
 166       "thread count mismatch %d : %d",
 167       (int)_daemon_threads_count->get_value(), daemon_count);
 168 
 169     _daemon_threads_count->dec(1);
 170   }
 171 
 172   // Counts are incremented at the same time, but atomic counts are
 173   // decremented earlier than perf counts.
 174   assert(_daemon_threads_count->get_value() >= daemon_count,
 175     "thread count mismatch %d : %d",
 176     (int)_daemon_threads_count->get_value(), daemon_count);
 177   assert(_live_threads_count->get_value() >= count,
 178     "thread count mismatch %d : %d",
 179     (int)_live_threads_count->get_value(), count);
 180   assert(_live_threads_count->get_value() > 0 ||
 181     (_live_threads_count->get_value() == 0 && count == 0 &&
 182     _daemon_threads_count->get_value() == 0 && daemon_count == 0),
 183     "thread counts should reach 0 at the same time, live %d,%d daemon %d,%d",
 184     (int)_live_threads_count->get_value(), count,
 185     (int)_daemon_threads_count->get_value(), daemon_count);
 186   assert(_daemon_threads_count->get_value() > 0 ||
 187     (_daemon_threads_count->get_value() == 0 && daemon_count == 0),
 188     "thread counts should reach 0 at the same time, daemon %d,%d",
 189     (int)_daemon_threads_count->get_value(), daemon_count);
 190 }
 191 
 192 void ThreadService::current_thread_exiting(JavaThread* jt) {
 193   // Do not count VM internal or JVMTI agent threads
 194   if (is_hidden_thread(jt)) {
 195     return;
 196   }
 197 
 198   assert(jt == JavaThread::current(), "Called by current thread");
 199   assert(!jt->is_terminated() && jt->is_exiting(), "must be exiting");
 200 
 201   decrement_thread_counts(jt);



 202 }
 203 
 204 // FIXME: JVMTI should call this function
 205 Handle ThreadService::get_current_contended_monitor(JavaThread* thread) {
 206   assert(thread != NULL, "should be non-NULL");
 207   debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 208 
 209   ObjectMonitor *wait_obj = thread->current_waiting_monitor();
 210 
 211   oop obj = NULL;
 212   if (wait_obj != NULL) {
 213     // thread is doing an Object.wait() call
 214     obj = (oop) wait_obj->object();
 215     assert(obj != NULL, "Object.wait() should have an object");
 216   } else {
 217     ObjectMonitor *enter_obj = thread->current_pending_monitor();
 218     if (enter_obj != NULL) {
 219       // thread is trying to enter() or raw_enter() an ObjectMonitor.
 220       obj = (oop) enter_obj->object();
 221     }


< prev index next >