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 } |