1.1 --- a/src/share/vm/services/management.cpp Fri Jan 07 03:38:19 2011 -0800 1.2 +++ b/src/share/vm/services/management.cpp Fri Jan 07 10:42:32 2011 -0500 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -101,12 +101,14 @@ 1.11 _optional_support.isCurrentThreadCpuTimeSupported = 0; 1.12 _optional_support.isOtherThreadCpuTimeSupported = 0; 1.13 } 1.14 + 1.15 _optional_support.isBootClassPathSupported = 1; 1.16 _optional_support.isObjectMonitorUsageSupported = 1; 1.17 #ifndef SERVICES_KERNEL 1.18 // This depends on the heap inspector 1.19 _optional_support.isSynchronizerUsageSupported = 1; 1.20 #endif // SERVICES_KERNEL 1.21 + _optional_support.isThreadAllocatedMemorySupported = 1; 1.22 } 1.23 1.24 void Management::initialize(TRAPS) { 1.25 @@ -386,11 +388,6 @@ 1.26 1.27 static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) { 1.28 int num_threads = ids_ah->length(); 1.29 - // should be non-empty array 1.30 - if (num_threads == 0) { 1.31 - THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 1.32 - "Empty array of thread IDs"); 1.33 - } 1.34 1.35 // Validate input thread IDs 1.36 int i = 0; 1.37 @@ -402,11 +399,9 @@ 1.38 "Invalid thread ID entry"); 1.39 } 1.40 } 1.41 - 1.42 } 1.43 1.44 static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) { 1.45 - 1.46 // check if the element of infoArray is of type ThreadInfo class 1.47 klassOop threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK); 1.48 klassOop element_klass = objArrayKlass::cast(infoArray_h->klass())->element_klass(); 1.49 @@ -414,7 +409,6 @@ 1.50 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 1.51 "infoArray element type is not ThreadInfo class"); 1.52 } 1.53 - 1.54 } 1.55 1.56 1.57 @@ -770,6 +764,45 @@ 1.58 return prev; 1.59 JVM_END 1.60 1.61 +// Gets an array containing the amount of memory allocated on the Java 1.62 +// heap for a set of threads (in bytes). Each element of the array is 1.63 +// the amount of memory allocated for the thread ID specified in the 1.64 +// corresponding entry in the given array of thread IDs; or -1 if the 1.65 +// thread does not exist or has terminated. 1.66 +JVM_ENTRY(void, jmm_GetThreadAllocatedMemory(JNIEnv *env, jlongArray ids, 1.67 + jlongArray sizeArray)) 1.68 + // Check if threads is null 1.69 + if (ids == NULL || sizeArray == NULL) { 1.70 + THROW(vmSymbols::java_lang_NullPointerException()); 1.71 + } 1.72 + 1.73 + ResourceMark rm(THREAD); 1.74 + typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids)); 1.75 + typeArrayHandle ids_ah(THREAD, ta); 1.76 + 1.77 + typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray)); 1.78 + typeArrayHandle sizeArray_h(THREAD, sa); 1.79 + 1.80 + // validate the thread id array 1.81 + validate_thread_id_array(ids_ah, CHECK); 1.82 + 1.83 + // sizeArray must be of the same length as the given array of thread IDs 1.84 + int num_threads = ids_ah->length(); 1.85 + if (num_threads != sizeArray_h->length()) { 1.86 + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 1.87 + "The length of the given long array does not match the length of " 1.88 + "the given array of thread IDs"); 1.89 + } 1.90 + 1.91 + MutexLockerEx ml(Threads_lock); 1.92 + for (int i = 0; i < num_threads; i++) { 1.93 + JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i)); 1.94 + if (java_thread != NULL) { 1.95 + sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes()); 1.96 + } 1.97 + } 1.98 +JVM_END 1.99 + 1.100 // Returns a java/lang/management/MemoryUsage object representing 1.101 // the memory usage for the heap or non-heap memory. 1.102 JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap)) 1.103 @@ -834,6 +867,8 @@ 1.104 return ThreadService::is_thread_monitoring_contention(); 1.105 case JMM_THREAD_CPU_TIME: 1.106 return ThreadService::is_thread_cpu_time_enabled(); 1.107 + case JMM_THREAD_ALLOCATED_MEMORY: 1.108 + return ThreadService::is_thread_allocated_memory_enabled(); 1.109 default: 1.110 assert(0, "Unrecognized attribute"); 1.111 return false; 1.112 @@ -851,6 +886,8 @@ 1.113 return ThreadService::set_thread_monitoring_contention(flag != 0); 1.114 case JMM_THREAD_CPU_TIME: 1.115 return ThreadService::set_thread_cpu_time_enabled(flag != 0); 1.116 + case JMM_THREAD_ALLOCATED_MEMORY: 1.117 + return ThreadService::set_thread_allocated_memory_enabled(flag != 0); 1.118 default: 1.119 assert(0, "Unrecognized attribute"); 1.120 return false; 1.121 @@ -1096,6 +1133,7 @@ 1.122 // maxDepth == 0 requests no stack trace. 1.123 // infoArray - array of ThreadInfo objects 1.124 // 1.125 +// QQQ - Why does this method return a value instead of void? 1.126 JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jobjectArray infoArray)) 1.127 // Check if threads is null 1.128 if (ids == NULL || infoArray == NULL) { 1.129 @@ -1159,7 +1197,6 @@ 1.130 } 1.131 } else { 1.132 // obtain thread dump with the specific list of threads with stack trace 1.133 - 1.134 do_thread_dump(&dump_result, 1.135 ids_ah, 1.136 num_threads, 1.137 @@ -1252,8 +1289,6 @@ 1.138 continue; 1.139 } 1.140 1.141 - 1.142 - 1.143 ThreadStackTrace* stacktrace = ts->get_stack_trace(); 1.144 assert(stacktrace != NULL, "Must have a stack trace dumped"); 1.145 1.146 @@ -1500,6 +1535,49 @@ 1.147 return -1; 1.148 JVM_END 1.149 1.150 +// Gets an array containing the CPU times consumed by a set of threads 1.151 +// (in nanoseconds). Each element of the array is the CPU time for the 1.152 +// thread ID specified in the corresponding entry in the given array 1.153 +// of thread IDs; or -1 if the thread does not exist or has terminated. 1.154 +// If user_sys_cpu_time = true, the sum of user level and system CPU time 1.155 +// for the given thread is returned; otherwise, only user level CPU time 1.156 +// is returned. 1.157 +JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids, 1.158 + jlongArray timeArray, 1.159 + jboolean user_sys_cpu_time)) 1.160 + // Check if threads is null 1.161 + if (ids == NULL || timeArray == NULL) { 1.162 + THROW(vmSymbols::java_lang_NullPointerException()); 1.163 + } 1.164 + 1.165 + ResourceMark rm(THREAD); 1.166 + typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids)); 1.167 + typeArrayHandle ids_ah(THREAD, ta); 1.168 + 1.169 + typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray)); 1.170 + typeArrayHandle timeArray_h(THREAD, tia); 1.171 + 1.172 + // validate the thread id array 1.173 + validate_thread_id_array(ids_ah, CHECK); 1.174 + 1.175 + // timeArray must be of the same length as the given array of thread IDs 1.176 + int num_threads = ids_ah->length(); 1.177 + if (num_threads != timeArray_h->length()) { 1.178 + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), 1.179 + "The length of the given long array does not match the length of " 1.180 + "the given array of thread IDs"); 1.181 + } 1.182 + 1.183 + MutexLockerEx ml(Threads_lock); 1.184 + for (int i = 0; i < num_threads; i++) { 1.185 + JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i)); 1.186 + if (java_thread != NULL) { 1.187 + timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread, 1.188 + user_sys_cpu_time != 0)); 1.189 + } 1.190 + } 1.191 +JVM_END 1.192 + 1.193 // Returns a String array of all VM global flag names 1.194 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env)) 1.195 // last flag entry is always NULL, so subtract 1 1.196 @@ -2020,7 +2098,7 @@ 1.197 jmm_GetMemoryManagers, 1.198 jmm_GetMemoryPoolUsage, 1.199 jmm_GetPeakMemoryPoolUsage, 1.200 - NULL, 1.201 + jmm_GetThreadAllocatedMemory, 1.202 jmm_GetMemoryUsage, 1.203 jmm_GetLongAttribute, 1.204 jmm_GetBoolAttribute, 1.205 @@ -2038,7 +2116,7 @@ 1.206 jmm_GetGCExtAttributeInfo, 1.207 jmm_GetLastGCStat, 1.208 jmm_GetThreadCpuTimeWithKind, 1.209 - NULL, 1.210 + jmm_GetThreadCpuTimesWithKind, 1.211 jmm_DumpHeap0, 1.212 jmm_FindDeadlockedThreads, 1.213 jmm_SetVMGlobal,