< prev index next >

src/share/vm/services/management.cpp

Print this page




  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:


< prev index next >