hotspot/src/share/vm/services/management.cpp
changeset 7724 a92d706dbdd5
parent 7397 5b173b4ca846
child 8076 96d498ec7ae1
equal deleted inserted replaced
7721:8fae37350972 7724:a92d706dbdd5
     1 /*
     1 /*
     2  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    99     _optional_support.isOtherThreadCpuTimeSupported = 1;
    99     _optional_support.isOtherThreadCpuTimeSupported = 1;
   100   } else {
   100   } else {
   101     _optional_support.isCurrentThreadCpuTimeSupported = 0;
   101     _optional_support.isCurrentThreadCpuTimeSupported = 0;
   102     _optional_support.isOtherThreadCpuTimeSupported = 0;
   102     _optional_support.isOtherThreadCpuTimeSupported = 0;
   103   }
   103   }
       
   104 
   104   _optional_support.isBootClassPathSupported = 1;
   105   _optional_support.isBootClassPathSupported = 1;
   105   _optional_support.isObjectMonitorUsageSupported = 1;
   106   _optional_support.isObjectMonitorUsageSupported = 1;
   106 #ifndef SERVICES_KERNEL
   107 #ifndef SERVICES_KERNEL
   107   // This depends on the heap inspector
   108   // This depends on the heap inspector
   108   _optional_support.isSynchronizerUsageSupported = 1;
   109   _optional_support.isSynchronizerUsageSupported = 1;
   109 #endif // SERVICES_KERNEL
   110 #endif // SERVICES_KERNEL
       
   111   _optional_support.isThreadAllocatedMemorySupported = 1;
   110 }
   112 }
   111 
   113 
   112 void Management::initialize(TRAPS) {
   114 void Management::initialize(TRAPS) {
   113   // Start the low memory detector thread
   115   // Start the low memory detector thread
   114   LowMemoryDetector::initialize();
   116   LowMemoryDetector::initialize();
   384   return MemoryService::get_memory_pool(ph);
   386   return MemoryService::get_memory_pool(ph);
   385 }
   387 }
   386 
   388 
   387 static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
   389 static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
   388   int num_threads = ids_ah->length();
   390   int num_threads = ids_ah->length();
   389   // should be non-empty array
       
   390   if (num_threads == 0) {
       
   391     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
       
   392               "Empty array of thread IDs");
       
   393   }
       
   394 
   391 
   395   // Validate input thread IDs
   392   // Validate input thread IDs
   396   int i = 0;
   393   int i = 0;
   397   for (i = 0; i < num_threads; i++) {
   394   for (i = 0; i < num_threads; i++) {
   398     jlong tid = ids_ah->long_at(i);
   395     jlong tid = ids_ah->long_at(i);
   400       // throw exception if invalid thread id.
   397       // throw exception if invalid thread id.
   401       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   398       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   402                 "Invalid thread ID entry");
   399                 "Invalid thread ID entry");
   403     }
   400     }
   404   }
   401   }
   405 
       
   406 }
   402 }
   407 
   403 
   408 static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
   404 static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
   409 
       
   410   // check if the element of infoArray is of type ThreadInfo class
   405   // check if the element of infoArray is of type ThreadInfo class
   411   klassOop threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
   406   klassOop threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
   412   klassOop element_klass = objArrayKlass::cast(infoArray_h->klass())->element_klass();
   407   klassOop element_klass = objArrayKlass::cast(infoArray_h->klass())->element_klass();
   413   if (element_klass != threadinfo_klass) {
   408   if (element_klass != threadinfo_klass) {
   414     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   409     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   415               "infoArray element type is not ThreadInfo class");
   410               "infoArray element type is not ThreadInfo class");
   416   }
   411   }
   417 
       
   418 }
   412 }
   419 
   413 
   420 
   414 
   421 static MemoryManager* get_memory_manager_from_jobject(jobject obj, TRAPS) {
   415 static MemoryManager* get_memory_manager_from_jobject(jobject obj, TRAPS) {
   422   if (obj == NULL) {
   416   if (obj == NULL) {
   768     LowMemoryDetector::detect_low_memory(pool);
   762     LowMemoryDetector::detect_low_memory(pool);
   769   }
   763   }
   770   return prev;
   764   return prev;
   771 JVM_END
   765 JVM_END
   772 
   766 
       
   767 // Gets an array containing the amount of memory allocated on the Java
       
   768 // heap for a set of threads (in bytes).  Each element of the array is
       
   769 // the amount of memory allocated for the thread ID specified in the
       
   770 // corresponding entry in the given array of thread IDs; or -1 if the
       
   771 // thread does not exist or has terminated.
       
   772 JVM_ENTRY(void, jmm_GetThreadAllocatedMemory(JNIEnv *env, jlongArray ids,
       
   773                                              jlongArray sizeArray))
       
   774   // Check if threads is null
       
   775   if (ids == NULL || sizeArray == NULL) {
       
   776     THROW(vmSymbols::java_lang_NullPointerException());
       
   777   }
       
   778 
       
   779   ResourceMark rm(THREAD);
       
   780   typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
       
   781   typeArrayHandle ids_ah(THREAD, ta);
       
   782 
       
   783   typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));
       
   784   typeArrayHandle sizeArray_h(THREAD, sa);
       
   785 
       
   786   // validate the thread id array
       
   787   validate_thread_id_array(ids_ah, CHECK);
       
   788 
       
   789   // sizeArray must be of the same length as the given array of thread IDs
       
   790   int num_threads = ids_ah->length();
       
   791   if (num_threads != sizeArray_h->length()) {
       
   792     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
       
   793               "The length of the given long array does not match the length of "
       
   794               "the given array of thread IDs");
       
   795   }
       
   796 
       
   797   MutexLockerEx ml(Threads_lock);
       
   798   for (int i = 0; i < num_threads; i++) {
       
   799     JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
       
   800     if (java_thread != NULL) {
       
   801       sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
       
   802     }
       
   803   }
       
   804 JVM_END
       
   805 
   773 // Returns a java/lang/management/MemoryUsage object representing
   806 // Returns a java/lang/management/MemoryUsage object representing
   774 // the memory usage for the heap or non-heap memory.
   807 // the memory usage for the heap or non-heap memory.
   775 JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
   808 JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
   776   ResourceMark rm(THREAD);
   809   ResourceMark rm(THREAD);
   777 
   810 
   832     return ClassLoadingService::get_verbose();
   865     return ClassLoadingService::get_verbose();
   833   case JMM_THREAD_CONTENTION_MONITORING:
   866   case JMM_THREAD_CONTENTION_MONITORING:
   834     return ThreadService::is_thread_monitoring_contention();
   867     return ThreadService::is_thread_monitoring_contention();
   835   case JMM_THREAD_CPU_TIME:
   868   case JMM_THREAD_CPU_TIME:
   836     return ThreadService::is_thread_cpu_time_enabled();
   869     return ThreadService::is_thread_cpu_time_enabled();
       
   870   case JMM_THREAD_ALLOCATED_MEMORY:
       
   871     return ThreadService::is_thread_allocated_memory_enabled();
   837   default:
   872   default:
   838     assert(0, "Unrecognized attribute");
   873     assert(0, "Unrecognized attribute");
   839     return false;
   874     return false;
   840   }
   875   }
   841 JVM_END
   876 JVM_END
   849     return ClassLoadingService::set_verbose(flag != 0);
   884     return ClassLoadingService::set_verbose(flag != 0);
   850   case JMM_THREAD_CONTENTION_MONITORING:
   885   case JMM_THREAD_CONTENTION_MONITORING:
   851     return ThreadService::set_thread_monitoring_contention(flag != 0);
   886     return ThreadService::set_thread_monitoring_contention(flag != 0);
   852   case JMM_THREAD_CPU_TIME:
   887   case JMM_THREAD_CPU_TIME:
   853     return ThreadService::set_thread_cpu_time_enabled(flag != 0);
   888     return ThreadService::set_thread_cpu_time_enabled(flag != 0);
       
   889   case JMM_THREAD_ALLOCATED_MEMORY:
       
   890     return ThreadService::set_thread_allocated_memory_enabled(flag != 0);
   854   default:
   891   default:
   855     assert(0, "Unrecognized attribute");
   892     assert(0, "Unrecognized attribute");
   856     return false;
   893     return false;
   857   }
   894   }
   858 JVM_END
   895 JVM_END
  1094 //   maxDepth  - the maximum depth of stack traces to be dumped:
  1131 //   maxDepth  - the maximum depth of stack traces to be dumped:
  1095 //               maxDepth == -1 requests to dump entire stack trace.
  1132 //               maxDepth == -1 requests to dump entire stack trace.
  1096 //               maxDepth == 0  requests no stack trace.
  1133 //               maxDepth == 0  requests no stack trace.
  1097 //   infoArray - array of ThreadInfo objects
  1134 //   infoArray - array of ThreadInfo objects
  1098 //
  1135 //
       
  1136 // QQQ - Why does this method return a value instead of void?
  1099 JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jobjectArray infoArray))
  1137 JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jobjectArray infoArray))
  1100   // Check if threads is null
  1138   // Check if threads is null
  1101   if (ids == NULL || infoArray == NULL) {
  1139   if (ids == NULL || infoArray == NULL) {
  1102     THROW_(vmSymbols::java_lang_NullPointerException(), -1);
  1140     THROW_(vmSymbols::java_lang_NullPointerException(), -1);
  1103   }
  1141   }
  1157         dump_result.add_thread_snapshot(ts);
  1195         dump_result.add_thread_snapshot(ts);
  1158       }
  1196       }
  1159     }
  1197     }
  1160   } else {
  1198   } else {
  1161     // obtain thread dump with the specific list of threads with stack trace
  1199     // obtain thread dump with the specific list of threads with stack trace
  1162 
       
  1163     do_thread_dump(&dump_result,
  1200     do_thread_dump(&dump_result,
  1164                    ids_ah,
  1201                    ids_ah,
  1165                    num_threads,
  1202                    num_threads,
  1166                    maxDepth,
  1203                    maxDepth,
  1167                    false, /* no locked monitor */
  1204                    false, /* no locked monitor */
  1249     if (ts->threadObj() == NULL) {
  1286     if (ts->threadObj() == NULL) {
  1250      // if the thread does not exist or now it is terminated, set threadinfo to NULL
  1287      // if the thread does not exist or now it is terminated, set threadinfo to NULL
  1251       result_h->obj_at_put(index, NULL);
  1288       result_h->obj_at_put(index, NULL);
  1252       continue;
  1289       continue;
  1253     }
  1290     }
  1254 
       
  1255 
       
  1256 
  1291 
  1257     ThreadStackTrace* stacktrace = ts->get_stack_trace();
  1292     ThreadStackTrace* stacktrace = ts->get_stack_trace();
  1258     assert(stacktrace != NULL, "Must have a stack trace dumped");
  1293     assert(stacktrace != NULL, "Must have a stack trace dumped");
  1259 
  1294 
  1260     // Create Object[] filled with locked monitors
  1295     // Create Object[] filled with locked monitors
  1496     if (java_thread != NULL) {
  1531     if (java_thread != NULL) {
  1497       return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);
  1532       return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);
  1498     }
  1533     }
  1499   }
  1534   }
  1500   return -1;
  1535   return -1;
       
  1536 JVM_END
       
  1537 
       
  1538 // Gets an array containing the CPU times consumed by a set of threads
       
  1539 // (in nanoseconds).  Each element of the array is the CPU time for the
       
  1540 // thread ID specified in the corresponding entry in the given array
       
  1541 // of thread IDs; or -1 if the thread does not exist or has terminated.
       
  1542 // If user_sys_cpu_time = true, the sum of user level and system CPU time
       
  1543 // for the given thread is returned; otherwise, only user level CPU time
       
  1544 // is returned.
       
  1545 JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,
       
  1546                                               jlongArray timeArray,
       
  1547                                               jboolean user_sys_cpu_time))
       
  1548   // Check if threads is null
       
  1549   if (ids == NULL || timeArray == NULL) {
       
  1550     THROW(vmSymbols::java_lang_NullPointerException());
       
  1551   }
       
  1552 
       
  1553   ResourceMark rm(THREAD);
       
  1554   typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
       
  1555   typeArrayHandle ids_ah(THREAD, ta);
       
  1556 
       
  1557   typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));
       
  1558   typeArrayHandle timeArray_h(THREAD, tia);
       
  1559 
       
  1560   // validate the thread id array
       
  1561   validate_thread_id_array(ids_ah, CHECK);
       
  1562 
       
  1563   // timeArray must be of the same length as the given array of thread IDs
       
  1564   int num_threads = ids_ah->length();
       
  1565   if (num_threads != timeArray_h->length()) {
       
  1566     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
       
  1567               "The length of the given long array does not match the length of "
       
  1568               "the given array of thread IDs");
       
  1569   }
       
  1570 
       
  1571   MutexLockerEx ml(Threads_lock);
       
  1572   for (int i = 0; i < num_threads; i++) {
       
  1573     JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
       
  1574     if (java_thread != NULL) {
       
  1575       timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
       
  1576                                                       user_sys_cpu_time != 0));
       
  1577     }
       
  1578   }
  1501 JVM_END
  1579 JVM_END
  1502 
  1580 
  1503 // Returns a String array of all VM global flag names
  1581 // Returns a String array of all VM global flag names
  1504 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
  1582 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
  1505   // last flag entry is always NULL, so subtract 1
  1583   // last flag entry is always NULL, so subtract 1
  2018   jmm_GetInputArgumentArray,
  2096   jmm_GetInputArgumentArray,
  2019   jmm_GetMemoryPools,
  2097   jmm_GetMemoryPools,
  2020   jmm_GetMemoryManagers,
  2098   jmm_GetMemoryManagers,
  2021   jmm_GetMemoryPoolUsage,
  2099   jmm_GetMemoryPoolUsage,
  2022   jmm_GetPeakMemoryPoolUsage,
  2100   jmm_GetPeakMemoryPoolUsage,
  2023   NULL,
  2101   jmm_GetThreadAllocatedMemory,
  2024   jmm_GetMemoryUsage,
  2102   jmm_GetMemoryUsage,
  2025   jmm_GetLongAttribute,
  2103   jmm_GetLongAttribute,
  2026   jmm_GetBoolAttribute,
  2104   jmm_GetBoolAttribute,
  2027   jmm_SetBoolAttribute,
  2105   jmm_SetBoolAttribute,
  2028   jmm_GetLongAttributes,
  2106   jmm_GetLongAttributes,
  2036   jmm_SetPoolThreshold,
  2114   jmm_SetPoolThreshold,
  2037   jmm_GetPoolCollectionUsage,
  2115   jmm_GetPoolCollectionUsage,
  2038   jmm_GetGCExtAttributeInfo,
  2116   jmm_GetGCExtAttributeInfo,
  2039   jmm_GetLastGCStat,
  2117   jmm_GetLastGCStat,
  2040   jmm_GetThreadCpuTimeWithKind,
  2118   jmm_GetThreadCpuTimeWithKind,
  2041   NULL,
  2119   jmm_GetThreadCpuTimesWithKind,
  2042   jmm_DumpHeap0,
  2120   jmm_DumpHeap0,
  2043   jmm_FindDeadlockedThreads,
  2121   jmm_FindDeadlockedThreads,
  2044   jmm_SetVMGlobal,
  2122   jmm_SetVMGlobal,
  2045   NULL,
  2123   NULL,
  2046   jmm_DumpThreads
  2124   jmm_DumpThreads