45 #include "services/diagnosticCommand.hpp"
46 #include "services/diagnosticFramework.hpp"
47 #include "services/writeableFlags.hpp"
48 #include "services/heapDumper.hpp"
49 #include "services/jmm.h"
50 #include "services/lowMemoryDetector.hpp"
51 #include "services/gcNotifier.hpp"
52 #include "services/nmtDCmd.hpp"
53 #include "services/management.hpp"
54 #include "services/memoryManager.hpp"
55 #include "services/memoryPool.hpp"
56 #include "services/memoryService.hpp"
57 #include "services/runtimeService.hpp"
58 #include "services/threadService.hpp"
59 #include "utilities/macros.hpp"
60
61 PerfVariable* Management::_begin_vm_creation_time = NULL;
62 PerfVariable* Management::_end_vm_creation_time = NULL;
63 PerfVariable* Management::_vm_init_done_time = NULL;
64
65 Klass* Management::_diagnosticCommandImpl_klass = NULL;
66 Klass* Management::_garbageCollectorExtImpl_klass = NULL;
67 Klass* Management::_garbageCollectorMXBean_klass = NULL;
68 Klass* Management::_gcInfo_klass = NULL;
69 Klass* Management::_managementFactoryHelper_klass = NULL;
70 Klass* Management::_memoryManagerMXBean_klass = NULL;
71 Klass* Management::_memoryPoolMXBean_klass = NULL;
72 Klass* Management::_memoryUsage_klass = NULL;
73 Klass* Management::_sensor_klass = NULL;
74 Klass* Management::_threadInfo_klass = NULL;
75
76 jmmOptionalSupport Management::_optional_support = {0};
77 TimeStamp Management::_stamp;
78
79 void management_init() {
80 #if INCLUDE_MANAGEMENT
81 Management::init();
82 ThreadService::init();
83 RuntimeService::init();
84 ClassLoadingService::init();
85 #else
86 ThreadService::init();
87 #endif // INCLUDE_MANAGEMENT
88 }
89
90 #if INCLUDE_MANAGEMENT
91
92 void Management::init() {
93 EXCEPTION_MARK;
94
139
140 void Management::initialize(TRAPS) {
141 // Start the service thread
142 ServiceThread::initialize();
143
144 if (ManagementServer) {
145 ResourceMark rm(THREAD);
146 HandleMark hm(THREAD);
147
148 // Load and initialize the jdk.internal.agent.Agent class
149 // invoke startAgent method to start the management server
150 Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
151 Klass* k = SystemDictionary::resolve_or_null(vmSymbols::jdk_internal_agent_Agent(),
152 loader,
153 Handle(),
154 THREAD);
155 if (k == NULL) {
156 vm_exit_during_initialization("Management agent initialization failure: "
157 "class jdk.internal.agent.Agent not found.");
158 }
159 instanceKlassHandle ik (THREAD, k);
160
161 JavaValue result(T_VOID);
162 JavaCalls::call_static(&result,
163 ik,
164 vmSymbols::startAgent_name(),
165 vmSymbols::void_method_signature(),
166 CHECK);
167 }
168 }
169
170 void Management::get_optional_support(jmmOptionalSupport* support) {
171 memcpy(support, &_optional_support, sizeof(jmmOptionalSupport));
172 }
173
174 Klass* Management::load_and_initialize_klass(Symbol* sh, TRAPS) {
175 Klass* k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL);
176 Klass* ik = initialize_klass(k, CHECK_NULL);
177 return ik;
178 }
179
180 Klass* Management::load_and_initialize_klass_or_null(Symbol* sh, TRAPS) {
181 Klass* k = SystemDictionary::resolve_or_null(sh, CHECK_NULL);
182 if (k == NULL) {
183 return NULL;
184 }
185 Klass* ik = initialize_klass(k, CHECK_NULL);
186 return ik;
187 }
188
189 Klass* Management::initialize_klass(Klass* k, TRAPS) {
190 instanceKlassHandle ik (THREAD, k);
191 if (ik->should_be_initialized()) {
192 ik->initialize(CHECK_NULL);
193 }
194 // If these classes change to not be owned by the boot loader, they need
195 // to be walked to keep their class loader alive in oops_do.
196 assert(ik->class_loader() == NULL, "need to follow in oops_do");
197 return ik();
198 }
199
200 void Management::record_vm_startup_time(jlong begin, jlong duration) {
201 // if the performance counter is not initialized,
202 // then vm initialization failed; simply return.
203 if (_begin_vm_creation_time == NULL) return;
204
205 _begin_vm_creation_time->set_value(begin);
206 _end_vm_creation_time->set_value(begin + duration);
207 PerfMemory::set_accessible(true);
208 }
209
210 jlong Management::timestamp() {
211 TimeStamp t;
212 t.update();
213 return t.ticks() - _stamp.ticks();
214 }
215
216 void Management::oops_do(OopClosure* f) {
217 MemoryService::oops_do(f);
218 ThreadService::oops_do(f);
219 }
220
221 Klass* Management::java_lang_management_ThreadInfo_klass(TRAPS) {
222 if (_threadInfo_klass == NULL) {
223 _threadInfo_klass = load_and_initialize_klass(vmSymbols::java_lang_management_ThreadInfo(), CHECK_NULL);
224 }
225 return _threadInfo_klass;
226 }
227
228 Klass* Management::java_lang_management_MemoryUsage_klass(TRAPS) {
229 if (_memoryUsage_klass == NULL) {
230 _memoryUsage_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryUsage(), CHECK_NULL);
231 }
232 return _memoryUsage_klass;
233 }
234
235 Klass* Management::java_lang_management_MemoryPoolMXBean_klass(TRAPS) {
236 if (_memoryPoolMXBean_klass == NULL) {
237 _memoryPoolMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryPoolMXBean(), CHECK_NULL);
238 }
239 return _memoryPoolMXBean_klass;
240 }
241
242 Klass* Management::java_lang_management_MemoryManagerMXBean_klass(TRAPS) {
243 if (_memoryManagerMXBean_klass == NULL) {
244 _memoryManagerMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryManagerMXBean(), CHECK_NULL);
245 }
246 return _memoryManagerMXBean_klass;
247 }
248
249 Klass* Management::java_lang_management_GarbageCollectorMXBean_klass(TRAPS) {
250 if (_garbageCollectorMXBean_klass == NULL) {
251 _garbageCollectorMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_GarbageCollectorMXBean(), CHECK_NULL);
252 }
253 return _garbageCollectorMXBean_klass;
254 }
255
256 Klass* Management::sun_management_Sensor_klass(TRAPS) {
257 if (_sensor_klass == NULL) {
258 _sensor_klass = load_and_initialize_klass(vmSymbols::sun_management_Sensor(), CHECK_NULL);
259 }
260 return _sensor_klass;
261 }
262
263 Klass* Management::sun_management_ManagementFactoryHelper_klass(TRAPS) {
264 if (_managementFactoryHelper_klass == NULL) {
265 _managementFactoryHelper_klass = load_and_initialize_klass(vmSymbols::sun_management_ManagementFactoryHelper(), CHECK_NULL);
266 }
267 return _managementFactoryHelper_klass;
268 }
269
270 Klass* Management::com_sun_management_internal_GarbageCollectorExtImpl_klass(TRAPS) {
271 if (_garbageCollectorExtImpl_klass == NULL) {
272 _garbageCollectorExtImpl_klass =
273 load_and_initialize_klass_or_null(vmSymbols::com_sun_management_internal_GarbageCollectorExtImpl(), CHECK_NULL);
274 }
275 return _garbageCollectorExtImpl_klass;
276 }
277
278 Klass* Management::com_sun_management_GcInfo_klass(TRAPS) {
279 if (_gcInfo_klass == NULL) {
280 _gcInfo_klass = load_and_initialize_klass(vmSymbols::com_sun_management_GcInfo(), CHECK_NULL);
281 }
282 return _gcInfo_klass;
283 }
284
285 Klass* Management::com_sun_management_internal_DiagnosticCommandImpl_klass(TRAPS) {
286 if (_diagnosticCommandImpl_klass == NULL) {
287 _diagnosticCommandImpl_klass = load_and_initialize_klass(vmSymbols::com_sun_management_internal_DiagnosticCommandImpl(), CHECK_NULL);
288 }
289 return _diagnosticCommandImpl_klass;
290 }
291
292 static void initialize_ThreadInfo_constructor_arguments(JavaCallArguments* args, ThreadSnapshot* snapshot, TRAPS) {
293 Handle snapshot_thread(THREAD, snapshot->threadObj());
294
295 jlong contended_time;
296 jlong waited_time;
297 if (ThreadService::is_thread_monitoring_contention()) {
298 contended_time = Management::ticks_to_ms(snapshot->contended_enter_ticks());
299 waited_time = Management::ticks_to_ms(snapshot->monitor_wait_ticks() + snapshot->sleep_ticks());
300 } else {
301 // set them to -1 if thread contention monitoring is disabled.
302 contended_time = max_julong;
303 waited_time = max_julong;
304 }
305
316 Handle stacktrace_h;
317 if (st != NULL) {
318 stacktrace_h = st->allocate_fill_stack_trace_element_array(CHECK);
319 } else {
320 stacktrace_h = Handle();
321 }
322
323 args->push_oop(snapshot_thread);
324 args->push_int(thread_status);
325 args->push_oop(Handle(THREAD, snapshot->blocker_object()));
326 args->push_oop(Handle(THREAD, snapshot->blocker_object_owner()));
327 args->push_long(snapshot->contended_enter_count());
328 args->push_long(contended_time);
329 args->push_long(snapshot->monitor_wait_count() + snapshot->sleep_count());
330 args->push_long(waited_time);
331 args->push_oop(stacktrace_h);
332 }
333
334 // Helper function to construct a ThreadInfo object
335 instanceOop Management::create_thread_info_instance(ThreadSnapshot* snapshot, TRAPS) {
336 Klass* k = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
337 instanceKlassHandle ik (THREAD, k);
338
339 JavaValue result(T_VOID);
340 JavaCallArguments args(14);
341
342 // First allocate a ThreadObj object and
343 // push the receiver as the first argument
344 Handle element = ik->allocate_instance_handle(CHECK_NULL);
345 args.push_oop(element);
346
347 // initialize the arguments for the ThreadInfo constructor
348 initialize_ThreadInfo_constructor_arguments(&args, snapshot, CHECK_NULL);
349
350 // Call ThreadInfo constructor with no locked monitors and synchronizers
351 JavaCalls::call_special(&result,
352 ik,
353 vmSymbols::object_initializer_name(),
354 vmSymbols::java_lang_management_ThreadInfo_constructor_signature(),
355 &args,
356 CHECK_NULL);
357
358 return (instanceOop) element();
359 }
360
361 instanceOop Management::create_thread_info_instance(ThreadSnapshot* snapshot,
362 objArrayHandle monitors_array,
363 typeArrayHandle depths_array,
364 objArrayHandle synchronizers_array,
365 TRAPS) {
366 Klass* k = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
367 instanceKlassHandle ik (THREAD, k);
368
369 JavaValue result(T_VOID);
370 JavaCallArguments args(17);
371
372 // First allocate a ThreadObj object and
373 // push the receiver as the first argument
374 Handle element = ik->allocate_instance_handle(CHECK_NULL);
375 args.push_oop(element);
376
377 // initialize the arguments for the ThreadInfo constructor
378 initialize_ThreadInfo_constructor_arguments(&args, snapshot, CHECK_NULL);
379
380 // push the locked monitors and synchronizers in the arguments
381 args.push_oop(monitors_array);
382 args.push_oop(depths_array);
383 args.push_oop(synchronizers_array);
384
385 // Call ThreadInfo constructor with locked monitors and synchronizers
386 JavaCalls::call_special(&result,
387 ik,
388 vmSymbols::object_initializer_name(),
389 vmSymbols::java_lang_management_ThreadInfo_with_locks_constructor_signature(),
390 &args,
391 CHECK_NULL);
392
393 return (instanceOop) element();
394 }
395
396
397 static GCMemoryManager* get_gc_memory_manager_from_jobject(jobject mgr, TRAPS) {
398 if (mgr == NULL) {
399 THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
400 }
401 oop mgr_obj = JNIHandles::resolve(mgr);
402 instanceHandle h(THREAD, (instanceOop) mgr_obj);
403
404 Klass* k = Management::java_lang_management_GarbageCollectorMXBean_klass(CHECK_NULL);
405 if (!h->is_a(k)) {
406 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
407 "the object is not an instance of java.lang.management.GarbageCollectorMXBean class",
408 NULL);
409 }
410
411 MemoryManager* gc = MemoryService::get_memory_manager(h);
412 if (gc == NULL || !gc->is_gc_memory_manager()) {
413 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
414 "Invalid GC memory manager",
415 NULL);
416 }
417 return (GCMemoryManager*) gc;
418 }
419
420 static MemoryPool* get_memory_pool_from_jobject(jobject obj, TRAPS) {
421 if (obj == NULL) {
422 THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
423 }
424
490 // Returns an array of java/lang/management/MemoryPoolMXBean object
491 // one for each memory pool if obj == null; otherwise returns
492 // an array of memory pools for a given memory manager if
493 // it is a valid memory manager.
494 JVM_ENTRY(jobjectArray, jmm_GetMemoryPools(JNIEnv* env, jobject obj))
495 ResourceMark rm(THREAD);
496
497 int num_memory_pools;
498 MemoryManager* mgr = NULL;
499 if (obj == NULL) {
500 num_memory_pools = MemoryService::num_memory_pools();
501 } else {
502 mgr = get_memory_manager_from_jobject(obj, CHECK_NULL);
503 if (mgr == NULL) {
504 return NULL;
505 }
506 num_memory_pools = mgr->num_memory_pools();
507 }
508
509 // Allocate the resulting MemoryPoolMXBean[] object
510 Klass* k = Management::java_lang_management_MemoryPoolMXBean_klass(CHECK_NULL);
511 instanceKlassHandle ik (THREAD, k);
512 objArrayOop r = oopFactory::new_objArray(ik(), num_memory_pools, CHECK_NULL);
513 objArrayHandle poolArray(THREAD, r);
514
515 if (mgr == NULL) {
516 // Get all memory pools
517 for (int i = 0; i < num_memory_pools; i++) {
518 MemoryPool* pool = MemoryService::get_memory_pool(i);
519 instanceOop p = pool->get_memory_pool_instance(CHECK_NULL);
520 instanceHandle ph(THREAD, p);
521 poolArray->obj_at_put(i, ph());
522 }
523 } else {
524 // Get memory pools managed by a given memory manager
525 for (int i = 0; i < num_memory_pools; i++) {
526 MemoryPool* pool = mgr->get_memory_pool(i);
527 instanceOop p = pool->get_memory_pool_instance(CHECK_NULL);
528 instanceHandle ph(THREAD, p);
529 poolArray->obj_at_put(i, ph());
530 }
531 }
532 return (jobjectArray) JNIHandles::make_local(env, poolArray());
535 // Returns an array of java/lang/management/MemoryManagerMXBean object
536 // one for each memory manager if obj == null; otherwise returns
537 // an array of memory managers for a given memory pool if
538 // it is a valid memory pool.
539 JVM_ENTRY(jobjectArray, jmm_GetMemoryManagers(JNIEnv* env, jobject obj))
540 ResourceMark rm(THREAD);
541
542 int num_mgrs;
543 MemoryPool* pool = NULL;
544 if (obj == NULL) {
545 num_mgrs = MemoryService::num_memory_managers();
546 } else {
547 pool = get_memory_pool_from_jobject(obj, CHECK_NULL);
548 if (pool == NULL) {
549 return NULL;
550 }
551 num_mgrs = pool->num_memory_managers();
552 }
553
554 // Allocate the resulting MemoryManagerMXBean[] object
555 Klass* k = Management::java_lang_management_MemoryManagerMXBean_klass(CHECK_NULL);
556 instanceKlassHandle ik (THREAD, k);
557 objArrayOop r = oopFactory::new_objArray(ik(), num_mgrs, CHECK_NULL);
558 objArrayHandle mgrArray(THREAD, r);
559
560 if (pool == NULL) {
561 // Get all memory managers
562 for (int i = 0; i < num_mgrs; i++) {
563 MemoryManager* mgr = MemoryService::get_memory_manager(i);
564 instanceOop p = mgr->get_memory_manager_instance(CHECK_NULL);
565 instanceHandle ph(THREAD, p);
566 mgrArray->obj_at_put(i, ph());
567 }
568 } else {
569 // Get memory managers for a given memory pool
570 for (int i = 0; i < num_mgrs; i++) {
571 MemoryManager* mgr = pool->get_memory_manager(i);
572 instanceOop p = mgr->get_memory_manager_instance(CHECK_NULL);
573 instanceHandle ph(THREAD, p);
574 mgrArray->obj_at_put(i, ph());
575 }
576 }
577 return (jobjectArray) JNIHandles::make_local(env, mgrArray());
612 // of a given memory pool after most recent GC.
613 JVM_ENTRY(jobject, jmm_GetPoolCollectionUsage(JNIEnv* env, jobject obj))
614 ResourceMark rm(THREAD);
615
616 MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_NULL);
617 if (pool != NULL && pool->is_collected_pool()) {
618 MemoryUsage usage = pool->get_last_collection_usage();
619 Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);
620 return JNIHandles::make_local(env, h());
621 } else {
622 return NULL;
623 }
624 JVM_END
625
626 // Sets the memory pool sensor for a threshold type
627 JVM_ENTRY(void, jmm_SetPoolSensor(JNIEnv* env, jobject obj, jmmThresholdType type, jobject sensorObj))
628 if (obj == NULL || sensorObj == NULL) {
629 THROW(vmSymbols::java_lang_NullPointerException());
630 }
631
632 Klass* sensor_klass = Management::sun_management_Sensor_klass(CHECK);
633 oop s = JNIHandles::resolve(sensorObj);
634 assert(s->is_instance(), "Sensor should be an instanceOop");
635 instanceHandle sensor_h(THREAD, (instanceOop) s);
636 if (!sensor_h->is_a(sensor_klass)) {
637 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
638 "Sensor is not an instance of sun.management.Sensor class");
639 }
640
641 MemoryPool* mpool = get_memory_pool_from_jobject(obj, CHECK);
642 assert(mpool != NULL, "MemoryPool should exist");
643
644 switch (type) {
645 case JMM_USAGE_THRESHOLD_HIGH:
646 case JMM_USAGE_THRESHOLD_LOW:
647 // have only one sensor for threshold high and low
648 mpool->set_usage_sensor_obj(sensor_h);
649 break;
650 case JMM_COLLECTION_USAGE_THRESHOLD_HIGH:
651 case JMM_COLLECTION_USAGE_THRESHOLD_LOW:
652 // have only one sensor for threshold high and low
1185 // obtain thread dump of a specific list of threads
1186 do_thread_dump(&dump_result,
1187 ids_ah,
1188 num_threads,
1189 -1, /* entire stack */
1190 (locked_monitors ? true : false), /* with locked monitors */
1191 (locked_synchronizers ? true : false), /* with locked synchronizers */
1192 CHECK_NULL);
1193 } else {
1194 // obtain thread dump of all threads
1195 VM_ThreadDump op(&dump_result,
1196 -1, /* entire stack */
1197 (locked_monitors ? true : false), /* with locked monitors */
1198 (locked_synchronizers ? true : false) /* with locked synchronizers */);
1199 VMThread::execute(&op);
1200 }
1201
1202 int num_snapshots = dump_result.num_snapshots();
1203
1204 // create the result ThreadInfo[] object
1205 Klass* k = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
1206 instanceKlassHandle ik (THREAD, k);
1207 objArrayOop r = oopFactory::new_objArray(ik(), num_snapshots, CHECK_NULL);
1208 objArrayHandle result_h(THREAD, r);
1209
1210 int index = 0;
1211 for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; ts = ts->next(), index++) {
1212 if (ts->threadObj() == NULL) {
1213 // if the thread does not exist or now it is terminated, set threadinfo to NULL
1214 result_h->obj_at_put(index, NULL);
1215 continue;
1216 }
1217
1218 ThreadStackTrace* stacktrace = ts->get_stack_trace();
1219 assert(stacktrace != NULL, "Must have a stack trace dumped");
1220
1221 // Create Object[] filled with locked monitors
1222 // Create int[] filled with the stack depth where a monitor was locked
1223 int num_frames = stacktrace->get_stack_depth();
1224 int num_locked_monitors = stacktrace->num_jni_locked_monitors();
1225
1226 // Count the total number of locked monitors
1227 for (int i = 0; i < num_frames; i++) {
1293 depths_array,
1294 synchronizers_array,
1295 CHECK_NULL);
1296 result_h->obj_at_put(index, info_obj);
1297 }
1298
1299 return (jobjectArray) JNIHandles::make_local(env, result_h());
1300 JVM_END
1301
1302 // Returns an array of Class objects.
1303 JVM_ENTRY(jobjectArray, jmm_GetLoadedClasses(JNIEnv *env))
1304 ResourceMark rm(THREAD);
1305
1306 LoadedClassesEnumerator lce(THREAD); // Pass current Thread as parameter
1307
1308 int num_classes = lce.num_loaded_classes();
1309 objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), num_classes, CHECK_0);
1310 objArrayHandle classes_ah(THREAD, r);
1311
1312 for (int i = 0; i < num_classes; i++) {
1313 KlassHandle kh = lce.get_klass(i);
1314 oop mirror = kh()->java_mirror();
1315 classes_ah->obj_at_put(i, mirror);
1316 }
1317
1318 return (jobjectArray) JNIHandles::make_local(env, classes_ah());
1319 JVM_END
1320
1321 // Reset statistic. Return true if the requested statistic is reset.
1322 // Otherwise, return false.
1323 //
1324 // Input parameters:
1325 // obj - specify which instance the statistic associated with to be reset
1326 // For PEAK_POOL_USAGE stat, obj is required to be a memory pool object.
1327 // For THREAD_CONTENTION_COUNT and TIME stat, obj is required to be a thread ID.
1328 // type - the type of statistic to be reset
1329 //
1330 JVM_ENTRY(jboolean, jmm_ResetStatistic(JNIEnv *env, jvalue obj, jmmStatisticType type))
1331 ResourceMark rm(THREAD);
1332
1333 switch (type) {
1334 case JMM_STAT_PEAK_THREAD_COUNT:
|
45 #include "services/diagnosticCommand.hpp"
46 #include "services/diagnosticFramework.hpp"
47 #include "services/writeableFlags.hpp"
48 #include "services/heapDumper.hpp"
49 #include "services/jmm.h"
50 #include "services/lowMemoryDetector.hpp"
51 #include "services/gcNotifier.hpp"
52 #include "services/nmtDCmd.hpp"
53 #include "services/management.hpp"
54 #include "services/memoryManager.hpp"
55 #include "services/memoryPool.hpp"
56 #include "services/memoryService.hpp"
57 #include "services/runtimeService.hpp"
58 #include "services/threadService.hpp"
59 #include "utilities/macros.hpp"
60
61 PerfVariable* Management::_begin_vm_creation_time = NULL;
62 PerfVariable* Management::_end_vm_creation_time = NULL;
63 PerfVariable* Management::_vm_init_done_time = NULL;
64
65 InstanceKlass* Management::_diagnosticCommandImpl_klass = NULL;
66 InstanceKlass* Management::_garbageCollectorExtImpl_klass = NULL;
67 InstanceKlass* Management::_garbageCollectorMXBean_klass = NULL;
68 InstanceKlass* Management::_gcInfo_klass = NULL;
69 InstanceKlass* Management::_managementFactoryHelper_klass = NULL;
70 InstanceKlass* Management::_memoryManagerMXBean_klass = NULL;
71 InstanceKlass* Management::_memoryPoolMXBean_klass = NULL;
72 InstanceKlass* Management::_memoryUsage_klass = NULL;
73 InstanceKlass* Management::_sensor_klass = NULL;
74 InstanceKlass* Management::_threadInfo_klass = NULL;
75
76 jmmOptionalSupport Management::_optional_support = {0};
77 TimeStamp Management::_stamp;
78
79 void management_init() {
80 #if INCLUDE_MANAGEMENT
81 Management::init();
82 ThreadService::init();
83 RuntimeService::init();
84 ClassLoadingService::init();
85 #else
86 ThreadService::init();
87 #endif // INCLUDE_MANAGEMENT
88 }
89
90 #if INCLUDE_MANAGEMENT
91
92 void Management::init() {
93 EXCEPTION_MARK;
94
139
140 void Management::initialize(TRAPS) {
141 // Start the service thread
142 ServiceThread::initialize();
143
144 if (ManagementServer) {
145 ResourceMark rm(THREAD);
146 HandleMark hm(THREAD);
147
148 // Load and initialize the jdk.internal.agent.Agent class
149 // invoke startAgent method to start the management server
150 Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
151 Klass* k = SystemDictionary::resolve_or_null(vmSymbols::jdk_internal_agent_Agent(),
152 loader,
153 Handle(),
154 THREAD);
155 if (k == NULL) {
156 vm_exit_during_initialization("Management agent initialization failure: "
157 "class jdk.internal.agent.Agent not found.");
158 }
159
160 JavaValue result(T_VOID);
161 JavaCalls::call_static(&result,
162 k,
163 vmSymbols::startAgent_name(),
164 vmSymbols::void_method_signature(),
165 CHECK);
166 }
167 }
168
169 void Management::get_optional_support(jmmOptionalSupport* support) {
170 memcpy(support, &_optional_support, sizeof(jmmOptionalSupport));
171 }
172
173 InstanceKlass* Management::load_and_initialize_klass(Symbol* sh, TRAPS) {
174 Klass* k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL);
175 return initialize_klass(k, CHECK_NULL);
176 }
177
178 InstanceKlass* Management::load_and_initialize_klass_or_null(Symbol* sh, TRAPS) {
179 Klass* k = SystemDictionary::resolve_or_null(sh, CHECK_NULL);
180 if (k == NULL) {
181 return NULL;
182 }
183 return initialize_klass(k, CHECK_NULL);
184 }
185
186 InstanceKlass* Management::initialize_klass(Klass* k, TRAPS) {
187 InstanceKlass* ik = InstanceKlass::cast(k);
188 if (ik->should_be_initialized()) {
189 ik->initialize(CHECK_NULL);
190 }
191 // If these classes change to not be owned by the boot loader, they need
192 // to be walked to keep their class loader alive in oops_do.
193 assert(ik->class_loader() == NULL, "need to follow in oops_do");
194 return ik;
195 }
196
197 void Management::record_vm_startup_time(jlong begin, jlong duration) {
198 // if the performance counter is not initialized,
199 // then vm initialization failed; simply return.
200 if (_begin_vm_creation_time == NULL) return;
201
202 _begin_vm_creation_time->set_value(begin);
203 _end_vm_creation_time->set_value(begin + duration);
204 PerfMemory::set_accessible(true);
205 }
206
207 jlong Management::timestamp() {
208 TimeStamp t;
209 t.update();
210 return t.ticks() - _stamp.ticks();
211 }
212
213 void Management::oops_do(OopClosure* f) {
214 MemoryService::oops_do(f);
215 ThreadService::oops_do(f);
216 }
217
218 InstanceKlass* Management::java_lang_management_ThreadInfo_klass(TRAPS) {
219 if (_threadInfo_klass == NULL) {
220 _threadInfo_klass = load_and_initialize_klass(vmSymbols::java_lang_management_ThreadInfo(), CHECK_NULL);
221 }
222 return _threadInfo_klass;
223 }
224
225 InstanceKlass* Management::java_lang_management_MemoryUsage_klass(TRAPS) {
226 if (_memoryUsage_klass == NULL) {
227 _memoryUsage_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryUsage(), CHECK_NULL);
228 }
229 return _memoryUsage_klass;
230 }
231
232 InstanceKlass* Management::java_lang_management_MemoryPoolMXBean_klass(TRAPS) {
233 if (_memoryPoolMXBean_klass == NULL) {
234 _memoryPoolMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryPoolMXBean(), CHECK_NULL);
235 }
236 return _memoryPoolMXBean_klass;
237 }
238
239 InstanceKlass* Management::java_lang_management_MemoryManagerMXBean_klass(TRAPS) {
240 if (_memoryManagerMXBean_klass == NULL) {
241 _memoryManagerMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryManagerMXBean(), CHECK_NULL);
242 }
243 return _memoryManagerMXBean_klass;
244 }
245
246 InstanceKlass* Management::java_lang_management_GarbageCollectorMXBean_klass(TRAPS) {
247 if (_garbageCollectorMXBean_klass == NULL) {
248 _garbageCollectorMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_GarbageCollectorMXBean(), CHECK_NULL);
249 }
250 return _garbageCollectorMXBean_klass;
251 }
252
253 InstanceKlass* Management::sun_management_Sensor_klass(TRAPS) {
254 if (_sensor_klass == NULL) {
255 _sensor_klass = load_and_initialize_klass(vmSymbols::sun_management_Sensor(), CHECK_NULL);
256 }
257 return _sensor_klass;
258 }
259
260 InstanceKlass* Management::sun_management_ManagementFactoryHelper_klass(TRAPS) {
261 if (_managementFactoryHelper_klass == NULL) {
262 _managementFactoryHelper_klass = load_and_initialize_klass(vmSymbols::sun_management_ManagementFactoryHelper(), CHECK_NULL);
263 }
264 return _managementFactoryHelper_klass;
265 }
266
267 InstanceKlass* Management::com_sun_management_internal_GarbageCollectorExtImpl_klass(TRAPS) {
268 if (_garbageCollectorExtImpl_klass == NULL) {
269 _garbageCollectorExtImpl_klass =
270 load_and_initialize_klass_or_null(vmSymbols::com_sun_management_internal_GarbageCollectorExtImpl(), CHECK_NULL);
271 }
272 return _garbageCollectorExtImpl_klass;
273 }
274
275 InstanceKlass* Management::com_sun_management_GcInfo_klass(TRAPS) {
276 if (_gcInfo_klass == NULL) {
277 _gcInfo_klass = load_and_initialize_klass(vmSymbols::com_sun_management_GcInfo(), CHECK_NULL);
278 }
279 return _gcInfo_klass;
280 }
281
282 InstanceKlass* Management::com_sun_management_internal_DiagnosticCommandImpl_klass(TRAPS) {
283 if (_diagnosticCommandImpl_klass == NULL) {
284 _diagnosticCommandImpl_klass = load_and_initialize_klass(vmSymbols::com_sun_management_internal_DiagnosticCommandImpl(), CHECK_NULL);
285 }
286 return _diagnosticCommandImpl_klass;
287 }
288
289 static void initialize_ThreadInfo_constructor_arguments(JavaCallArguments* args, ThreadSnapshot* snapshot, TRAPS) {
290 Handle snapshot_thread(THREAD, snapshot->threadObj());
291
292 jlong contended_time;
293 jlong waited_time;
294 if (ThreadService::is_thread_monitoring_contention()) {
295 contended_time = Management::ticks_to_ms(snapshot->contended_enter_ticks());
296 waited_time = Management::ticks_to_ms(snapshot->monitor_wait_ticks() + snapshot->sleep_ticks());
297 } else {
298 // set them to -1 if thread contention monitoring is disabled.
299 contended_time = max_julong;
300 waited_time = max_julong;
301 }
302
313 Handle stacktrace_h;
314 if (st != NULL) {
315 stacktrace_h = st->allocate_fill_stack_trace_element_array(CHECK);
316 } else {
317 stacktrace_h = Handle();
318 }
319
320 args->push_oop(snapshot_thread);
321 args->push_int(thread_status);
322 args->push_oop(Handle(THREAD, snapshot->blocker_object()));
323 args->push_oop(Handle(THREAD, snapshot->blocker_object_owner()));
324 args->push_long(snapshot->contended_enter_count());
325 args->push_long(contended_time);
326 args->push_long(snapshot->monitor_wait_count() + snapshot->sleep_count());
327 args->push_long(waited_time);
328 args->push_oop(stacktrace_h);
329 }
330
331 // Helper function to construct a ThreadInfo object
332 instanceOop Management::create_thread_info_instance(ThreadSnapshot* snapshot, TRAPS) {
333 InstanceKlass* ik = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
334
335 JavaValue result(T_VOID);
336 JavaCallArguments args(14);
337
338 // First allocate a ThreadObj object and
339 // push the receiver as the first argument
340 Handle element = ik->allocate_instance_handle(CHECK_NULL);
341 args.push_oop(element);
342
343 // initialize the arguments for the ThreadInfo constructor
344 initialize_ThreadInfo_constructor_arguments(&args, snapshot, CHECK_NULL);
345
346 // Call ThreadInfo constructor with no locked monitors and synchronizers
347 JavaCalls::call_special(&result,
348 ik,
349 vmSymbols::object_initializer_name(),
350 vmSymbols::java_lang_management_ThreadInfo_constructor_signature(),
351 &args,
352 CHECK_NULL);
353
354 return (instanceOop) element();
355 }
356
357 instanceOop Management::create_thread_info_instance(ThreadSnapshot* snapshot,
358 objArrayHandle monitors_array,
359 typeArrayHandle depths_array,
360 objArrayHandle synchronizers_array,
361 TRAPS) {
362 InstanceKlass* ik = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
363
364 JavaValue result(T_VOID);
365 JavaCallArguments args(17);
366
367 // First allocate a ThreadObj object and
368 // push the receiver as the first argument
369 Handle element = ik->allocate_instance_handle(CHECK_NULL);
370 args.push_oop(element);
371
372 // initialize the arguments for the ThreadInfo constructor
373 initialize_ThreadInfo_constructor_arguments(&args, snapshot, CHECK_NULL);
374
375 // push the locked monitors and synchronizers in the arguments
376 args.push_oop(monitors_array);
377 args.push_oop(depths_array);
378 args.push_oop(synchronizers_array);
379
380 // Call ThreadInfo constructor with locked monitors and synchronizers
381 JavaCalls::call_special(&result,
382 ik,
383 vmSymbols::object_initializer_name(),
384 vmSymbols::java_lang_management_ThreadInfo_with_locks_constructor_signature(),
385 &args,
386 CHECK_NULL);
387
388 return (instanceOop) element();
389 }
390
391
392 static GCMemoryManager* get_gc_memory_manager_from_jobject(jobject mgr, TRAPS) {
393 if (mgr == NULL) {
394 THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
395 }
396 oop mgr_obj = JNIHandles::resolve(mgr);
397 instanceHandle h(THREAD, (instanceOop) mgr_obj);
398
399 InstanceKlass* k = Management::java_lang_management_GarbageCollectorMXBean_klass(CHECK_NULL);
400 if (!h->is_a(k)) {
401 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
402 "the object is not an instance of java.lang.management.GarbageCollectorMXBean class",
403 NULL);
404 }
405
406 MemoryManager* gc = MemoryService::get_memory_manager(h);
407 if (gc == NULL || !gc->is_gc_memory_manager()) {
408 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
409 "Invalid GC memory manager",
410 NULL);
411 }
412 return (GCMemoryManager*) gc;
413 }
414
415 static MemoryPool* get_memory_pool_from_jobject(jobject obj, TRAPS) {
416 if (obj == NULL) {
417 THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
418 }
419
485 // Returns an array of java/lang/management/MemoryPoolMXBean object
486 // one for each memory pool if obj == null; otherwise returns
487 // an array of memory pools for a given memory manager if
488 // it is a valid memory manager.
489 JVM_ENTRY(jobjectArray, jmm_GetMemoryPools(JNIEnv* env, jobject obj))
490 ResourceMark rm(THREAD);
491
492 int num_memory_pools;
493 MemoryManager* mgr = NULL;
494 if (obj == NULL) {
495 num_memory_pools = MemoryService::num_memory_pools();
496 } else {
497 mgr = get_memory_manager_from_jobject(obj, CHECK_NULL);
498 if (mgr == NULL) {
499 return NULL;
500 }
501 num_memory_pools = mgr->num_memory_pools();
502 }
503
504 // Allocate the resulting MemoryPoolMXBean[] object
505 InstanceKlass* ik = Management::java_lang_management_MemoryPoolMXBean_klass(CHECK_NULL);
506 objArrayOop r = oopFactory::new_objArray(ik, num_memory_pools, CHECK_NULL);
507 objArrayHandle poolArray(THREAD, r);
508
509 if (mgr == NULL) {
510 // Get all memory pools
511 for (int i = 0; i < num_memory_pools; i++) {
512 MemoryPool* pool = MemoryService::get_memory_pool(i);
513 instanceOop p = pool->get_memory_pool_instance(CHECK_NULL);
514 instanceHandle ph(THREAD, p);
515 poolArray->obj_at_put(i, ph());
516 }
517 } else {
518 // Get memory pools managed by a given memory manager
519 for (int i = 0; i < num_memory_pools; i++) {
520 MemoryPool* pool = mgr->get_memory_pool(i);
521 instanceOop p = pool->get_memory_pool_instance(CHECK_NULL);
522 instanceHandle ph(THREAD, p);
523 poolArray->obj_at_put(i, ph());
524 }
525 }
526 return (jobjectArray) JNIHandles::make_local(env, poolArray());
529 // Returns an array of java/lang/management/MemoryManagerMXBean object
530 // one for each memory manager if obj == null; otherwise returns
531 // an array of memory managers for a given memory pool if
532 // it is a valid memory pool.
533 JVM_ENTRY(jobjectArray, jmm_GetMemoryManagers(JNIEnv* env, jobject obj))
534 ResourceMark rm(THREAD);
535
536 int num_mgrs;
537 MemoryPool* pool = NULL;
538 if (obj == NULL) {
539 num_mgrs = MemoryService::num_memory_managers();
540 } else {
541 pool = get_memory_pool_from_jobject(obj, CHECK_NULL);
542 if (pool == NULL) {
543 return NULL;
544 }
545 num_mgrs = pool->num_memory_managers();
546 }
547
548 // Allocate the resulting MemoryManagerMXBean[] object
549 InstanceKlass* ik = Management::java_lang_management_MemoryManagerMXBean_klass(CHECK_NULL);
550 objArrayOop r = oopFactory::new_objArray(ik, num_mgrs, CHECK_NULL);
551 objArrayHandle mgrArray(THREAD, r);
552
553 if (pool == NULL) {
554 // Get all memory managers
555 for (int i = 0; i < num_mgrs; i++) {
556 MemoryManager* mgr = MemoryService::get_memory_manager(i);
557 instanceOop p = mgr->get_memory_manager_instance(CHECK_NULL);
558 instanceHandle ph(THREAD, p);
559 mgrArray->obj_at_put(i, ph());
560 }
561 } else {
562 // Get memory managers for a given memory pool
563 for (int i = 0; i < num_mgrs; i++) {
564 MemoryManager* mgr = pool->get_memory_manager(i);
565 instanceOop p = mgr->get_memory_manager_instance(CHECK_NULL);
566 instanceHandle ph(THREAD, p);
567 mgrArray->obj_at_put(i, ph());
568 }
569 }
570 return (jobjectArray) JNIHandles::make_local(env, mgrArray());
605 // of a given memory pool after most recent GC.
606 JVM_ENTRY(jobject, jmm_GetPoolCollectionUsage(JNIEnv* env, jobject obj))
607 ResourceMark rm(THREAD);
608
609 MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_NULL);
610 if (pool != NULL && pool->is_collected_pool()) {
611 MemoryUsage usage = pool->get_last_collection_usage();
612 Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);
613 return JNIHandles::make_local(env, h());
614 } else {
615 return NULL;
616 }
617 JVM_END
618
619 // Sets the memory pool sensor for a threshold type
620 JVM_ENTRY(void, jmm_SetPoolSensor(JNIEnv* env, jobject obj, jmmThresholdType type, jobject sensorObj))
621 if (obj == NULL || sensorObj == NULL) {
622 THROW(vmSymbols::java_lang_NullPointerException());
623 }
624
625 InstanceKlass* sensor_klass = Management::sun_management_Sensor_klass(CHECK);
626 oop s = JNIHandles::resolve(sensorObj);
627 assert(s->is_instance(), "Sensor should be an instanceOop");
628 instanceHandle sensor_h(THREAD, (instanceOop) s);
629 if (!sensor_h->is_a(sensor_klass)) {
630 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
631 "Sensor is not an instance of sun.management.Sensor class");
632 }
633
634 MemoryPool* mpool = get_memory_pool_from_jobject(obj, CHECK);
635 assert(mpool != NULL, "MemoryPool should exist");
636
637 switch (type) {
638 case JMM_USAGE_THRESHOLD_HIGH:
639 case JMM_USAGE_THRESHOLD_LOW:
640 // have only one sensor for threshold high and low
641 mpool->set_usage_sensor_obj(sensor_h);
642 break;
643 case JMM_COLLECTION_USAGE_THRESHOLD_HIGH:
644 case JMM_COLLECTION_USAGE_THRESHOLD_LOW:
645 // have only one sensor for threshold high and low
1178 // obtain thread dump of a specific list of threads
1179 do_thread_dump(&dump_result,
1180 ids_ah,
1181 num_threads,
1182 -1, /* entire stack */
1183 (locked_monitors ? true : false), /* with locked monitors */
1184 (locked_synchronizers ? true : false), /* with locked synchronizers */
1185 CHECK_NULL);
1186 } else {
1187 // obtain thread dump of all threads
1188 VM_ThreadDump op(&dump_result,
1189 -1, /* entire stack */
1190 (locked_monitors ? true : false), /* with locked monitors */
1191 (locked_synchronizers ? true : false) /* with locked synchronizers */);
1192 VMThread::execute(&op);
1193 }
1194
1195 int num_snapshots = dump_result.num_snapshots();
1196
1197 // create the result ThreadInfo[] object
1198 InstanceKlass* ik = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
1199 objArrayOop r = oopFactory::new_objArray(ik, num_snapshots, CHECK_NULL);
1200 objArrayHandle result_h(THREAD, r);
1201
1202 int index = 0;
1203 for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; ts = ts->next(), index++) {
1204 if (ts->threadObj() == NULL) {
1205 // if the thread does not exist or now it is terminated, set threadinfo to NULL
1206 result_h->obj_at_put(index, NULL);
1207 continue;
1208 }
1209
1210 ThreadStackTrace* stacktrace = ts->get_stack_trace();
1211 assert(stacktrace != NULL, "Must have a stack trace dumped");
1212
1213 // Create Object[] filled with locked monitors
1214 // Create int[] filled with the stack depth where a monitor was locked
1215 int num_frames = stacktrace->get_stack_depth();
1216 int num_locked_monitors = stacktrace->num_jni_locked_monitors();
1217
1218 // Count the total number of locked monitors
1219 for (int i = 0; i < num_frames; i++) {
1285 depths_array,
1286 synchronizers_array,
1287 CHECK_NULL);
1288 result_h->obj_at_put(index, info_obj);
1289 }
1290
1291 return (jobjectArray) JNIHandles::make_local(env, result_h());
1292 JVM_END
1293
1294 // Returns an array of Class objects.
1295 JVM_ENTRY(jobjectArray, jmm_GetLoadedClasses(JNIEnv *env))
1296 ResourceMark rm(THREAD);
1297
1298 LoadedClassesEnumerator lce(THREAD); // Pass current Thread as parameter
1299
1300 int num_classes = lce.num_loaded_classes();
1301 objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), num_classes, CHECK_0);
1302 objArrayHandle classes_ah(THREAD, r);
1303
1304 for (int i = 0; i < num_classes; i++) {
1305 Klass* k = lce.get_klass(i);
1306 oop mirror = k->java_mirror();
1307 classes_ah->obj_at_put(i, mirror);
1308 }
1309
1310 return (jobjectArray) JNIHandles::make_local(env, classes_ah());
1311 JVM_END
1312
1313 // Reset statistic. Return true if the requested statistic is reset.
1314 // Otherwise, return false.
1315 //
1316 // Input parameters:
1317 // obj - specify which instance the statistic associated with to be reset
1318 // For PEAK_POOL_USAGE stat, obj is required to be a memory pool object.
1319 // For THREAD_CONTENTION_COUNT and TIME stat, obj is required to be a thread ID.
1320 // type - the type of statistic to be reset
1321 //
1322 JVM_ENTRY(jboolean, jmm_ResetStatistic(JNIEnv *env, jvalue obj, jmmStatisticType type))
1323 ResourceMark rm(THREAD);
1324
1325 switch (type) {
1326 case JMM_STAT_PEAK_THREAD_COUNT:
|