提交 683c0770 编写于 作者: P phh

6173675: M&M: approximate memory allocation rate/amount per thread

Summary: Subclass com.sun.management.ThreadMXBean from java.lang.management.ThreadMXBean, add getAllocatedBytes() and friends to c.s.m.ThreadMXBean and have sun.management.ThreadImpl implement c.s.m.ThreadMXBean rather than j.l.m.ThreadMXBean.
Reviewed-by: mchung, alanb, dholmes, emcmanus
上级 069126ea
#
# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
......@@ -70,14 +70,18 @@ SUNWprivate_1.1 {
Java_sun_management_ThreadImpl_dumpThreads0;
Java_sun_management_ThreadImpl_findDeadlockedThreads0;
Java_sun_management_ThreadImpl_findMonitorDeadlockedThreads0;
Java_sun_management_ThreadImpl_getThreadInfo0;
Java_sun_management_ThreadImpl_getThreadInfo1;
Java_sun_management_ThreadImpl_getThreads;
Java_sun_management_ThreadImpl_getThreadTotalCpuTime0;
Java_sun_management_ThreadImpl_getThreadTotalCpuTime1;
Java_sun_management_ThreadImpl_getThreadUserCpuTime0;
Java_sun_management_ThreadImpl_getThreadUserCpuTime1;
Java_sun_management_ThreadImpl_getThreadAllocatedMemory1;
Java_sun_management_ThreadImpl_resetContentionTimes0;
Java_sun_management_ThreadImpl_resetPeakThreadCount0;
Java_sun_management_ThreadImpl_setThreadContentionMonitoringEnabled0;
Java_sun_management_ThreadImpl_setThreadCpuTimeEnabled0;
Java_sun_management_ThreadImpl_setThreadAllocatedMemoryEnabled0;
Java_sun_management_VMManagementImpl_getAvailableProcessors;
Java_sun_management_VMManagementImpl_getClassInitializationTime;
Java_sun_management_VMManagementImpl_getClassLoadingTime;
......@@ -106,6 +110,7 @@ SUNWprivate_1.1 {
Java_sun_management_VMManagementImpl_initOptionalSupportFields;
Java_sun_management_VMManagementImpl_isThreadContentionMonitoringEnabled;
Java_sun_management_VMManagementImpl_isThreadCpuTimeEnabled;
Java_sun_management_VMManagementImpl_isThreadAllocatedMemoryEnabled;
JNI_OnLoad;
local:
*;
......
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.management;
import java.util.Map;
/**
* Platform-specific management interface for the thread system
* of the Java virtual machine.
* <p>
* This platform extension is only available to a thread
* implementation that supports this extension.
*
* @author Paul Hohensee
* @since 6u25
*/
public interface ThreadMXBean extends java.lang.management.ThreadMXBean {
/**
* Returns the total CPU time for each thread whose ID is
* in the input array {@code ids} in nanoseconds.
* The returned values are of nanoseconds precision but
* not necessarily nanoseconds accuracy.
* <p>
* This method is equivalent to calling the
* {@link ThreadMXBean#getThreadCpuTime(long)}
* method for each thread ID in the input array {@code ids} and setting the
* returned value in the corresponding element of the returned array.
*
* @param ids an array of thread IDs.
* @return an array of long values, each of which is the amount of CPU
* time the thread whose ID is in the corresponding element of the input
* array of IDs has used,
* if the thread of a specified ID exists, the thread is alive,
* and CPU time measurement is enabled;
* {@code -1} otherwise.
*
* @throws NullPointerException if {@code ids} is {@code null}
* @throws IllegalArgumentException if any element in the input array
* {@code ids} is {@code <=} {@code 0}.
* @throws java.lang.UnsupportedOperationException if the Java
* virtual machine implementation does not support CPU time
* measurement.
*
* @see ThreadMXBean#getThreadCpuTime(long)
* @see #getThreadUserTime
* @see ThreadMXBean#isThreadCpuTimeSupported
* @see ThreadMXBean#isThreadCpuTimeEnabled
* @see ThreadMXBean#setThreadCpuTimeEnabled
*/
public long[] getThreadCpuTime(long[] ids);
/**
* Returns the CPU time that each thread whose ID is in the input array
* {@code ids} has executed in user mode in nanoseconds.
* The returned values are of nanoseconds precision but
* not necessarily nanoseconds accuracy.
* <p>
* This method is equivalent to calling the
* {@link ThreadMXBean#getThreadUserTime(long)}
* method for each thread ID in the input array {@code ids} and setting the
* returned value in the corresponding element of the returned array.
*
* @param ids an array of thread IDs.
* @return an array of long values, each of which is the amount of user
* mode CPU time the thread whose ID is in the corresponding element of
* the input array of IDs has used,
* if the thread of a specified ID exists, the thread is alive,
* and CPU time measurement is enabled;
* {@code -1} otherwise.
*
* @throws NullPointerException if {@code ids} is {@code null}
* @throws IllegalArgumentException if any element in the input array
* {@code ids} is {@code <=} {@code 0}.
* @throws java.lang.UnsupportedOperationException if the Java
* virtual machine implementation does not support CPU time
* measurement.
*
* @see ThreadMXBean#getThreadUserTime(long)
* @see #getThreadCpuTime
* @see ThreadMXBean#isThreadCpuTimeSupported
* @see ThreadMXBean#isThreadCpuTimeEnabled
* @see ThreadMXBean#setThreadCpuTimeEnabled
*/
public long[] getThreadUserTime(long[] ids);
/**
* Returns an approximation of the total amount of memory, in bytes,
* allocated in heap memory for the thread of the specified ID.
* The returned value is an approximation because some Java virtual machine
* implementations may use object allocation mechanisms that result in a
* delay between the time an object is allocated and the time its size is
* recorded.
* <p>
* If the thread of the specified ID is not alive or does not exist,
* this method returns {@code -1}. If thread memory allocation measurement
* is disabled, this method returns {@code -1}.
* A thread is alive if it has been started and has not yet died.
* <p>
* If thread memory allocation measurement is enabled after the thread has
* started, the Java virtual machine implementation may choose any time up
* to and including the time that the capability is enabled as the point
* where thread memory allocation measurement starts.
*
* @param id the thread ID of a thread
* @return an approximation of the total memory allocated, in bytes, in
* heap memory for a thread of the specified ID
* if the thread of the specified ID exists, the thread is alive,
* and thread memory allocation measurement is enabled;
* {@code -1} otherwise.
*
* @throws IllegalArgumentException if {@code id} {@code <=} {@code 0}.
* @throws java.lang.UnsupportedOperationException if the Java virtual
* machine implementation does not support thread memory allocation
* measurement.
*
* @see #isThreadAllocatedMemorySupported
* @see #isThreadAllocatedMemoryEnabled
* @see #setThreadAllocatedMemoryEnabled
*/
public long getThreadAllocatedBytes(long id);
/**
* Returns an approximation of the total amount of memory, in bytes,
* allocated in heap memory for each thread whose ID is in the input
* array {@code ids}.
* The returned values are approximations because some Java virtual machine
* implementations may use object allocation mechanisms that result in a
* delay between the time an object is allocated and the time its size is
* recorded.
* <p>
* This method is equivalent to calling the
* {@link #getThreadAllocatedBytes(long)}
* method for each thread ID in the input array {@code ids} and setting the
* returned value in the corresponding element of the returned array.
*
* @param ids an array of thread IDs.
* @return an array of long values, each of which is an approximation of
* the total memory allocated, in bytes, in heap memory for the thread
* whose ID is in the corresponding element of the input array of IDs.
*
* @throws NullPointerException if {@code ids} is {@code null}
* @throws IllegalArgumentException if any element in the input array
* {@code ids} is {@code <=} {@code 0}.
* @throws java.lang.UnsupportedOperationException if the Java virtual
* machine implementation does not support thread memory allocation
* measurement.
*
* @see #getThreadAllocatedBytes(long)
* @see #isThreadAllocatedMemorySupported
* @see #isThreadAllocatedMemoryEnabled
* @see #setThreadAllocatedMemoryEnabled
*/
public long[] getThreadAllocatedBytes(long[] ids);
/**
* Tests if the Java virtual machine implementation supports thread memory
* allocation measurement.
*
* @return
* {@code true}
* if the Java virtual machine implementation supports thread memory
* allocation measurement;
* {@code false} otherwise.
*/
public boolean isThreadAllocatedMemorySupported();
/**
* Tests if thread memory allocation measurement is enabled.
*
* @return {@code true} if thread memory allocation measurement is enabled;
* {@code false} otherwise.
*
* @throws java.lang.UnsupportedOperationException if the Java virtual
* machine does not support thread memory allocation measurement.
*
* @see #isThreadAllocatedMemorySupported
*/
public boolean isThreadAllocatedMemoryEnabled();
/**
* Enables or disables thread memory allocation measurement. The default
* is platform dependent.
*
* @param enable {@code true} to enable;
* {@code false} to disable.
*
* @throws java.lang.UnsupportedOperationException if the Java virtual
* machine does not support thread memory allocation measurement.
*
* @throws java.lang.SecurityException if a security manager
* exists and the caller does not have
* ManagementPermission("control").
*
* @see #isThreadAllocatedMemorySupported
*/
public void setThreadAllocatedMemoryEnabled(boolean enable);
}
/*
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,7 +25,6 @@
package sun.management;
import java.lang.management.ThreadMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
......@@ -39,13 +38,14 @@ import javax.management.ObjectName;
* ManagementFactory.getThreadMXBean() returns an instance
* of this class.
*/
class ThreadImpl implements ThreadMXBean {
class ThreadImpl implements com.sun.management.ThreadMXBean {
private final VMManagement jvm;
// default for thread contention monitoring is disabled.
private boolean contentionMonitoringEnabled = false;
private boolean cpuTimeEnabled;
private boolean allocatedMemoryEnabled;
/**
* Constructor of ThreadImpl class.
......@@ -53,6 +53,7 @@ class ThreadImpl implements ThreadMXBean {
ThreadImpl(VMManagement vm) {
this.jvm = vm;
this.cpuTimeEnabled = jvm.isThreadCpuTimeEnabled();
this.allocatedMemoryEnabled = jvm.isThreadAllocatedMemoryEnabled();
}
public int getThreadCount() {
......@@ -91,6 +92,10 @@ class ThreadImpl implements ThreadMXBean {
return jvm.isCurrentThreadCpuTimeSupported();
}
public boolean isThreadAllocatedMemorySupported() {
return jvm.isThreadAllocatedMemorySupported();
}
public boolean isThreadCpuTimeEnabled() {
if (!isThreadCpuTimeSupported() &&
!isCurrentThreadCpuTimeSupported()) {
......@@ -100,6 +105,14 @@ class ThreadImpl implements ThreadMXBean {
return cpuTimeEnabled;
}
public boolean isThreadAllocatedMemoryEnabled() {
if (!isThreadAllocatedMemorySupported()) {
throw new UnsupportedOperationException(
"Thread allocated memory measurement is not supported");
}
return allocatedMemoryEnabled;
}
public long[] getAllThreadIds() {
Util.checkMonitorAccess();
......@@ -114,11 +127,6 @@ class ThreadImpl implements ThreadMXBean {
}
public ThreadInfo getThreadInfo(long id) {
if (id <= 0) {
throw new IllegalArgumentException(
"Invalid thread ID parameter: " + id);
}
long[] ids = new long[1];
ids[0] = id;
final ThreadInfo[] infos = getThreadInfo(ids, 0);
......@@ -126,15 +134,6 @@ class ThreadImpl implements ThreadMXBean {
}
public ThreadInfo getThreadInfo(long id, int maxDepth) {
if (id <= 0) {
throw new IllegalArgumentException(
"Invalid thread ID parameter: " + id);
}
if (maxDepth < 0) {
throw new IllegalArgumentException(
"Invalid maxDepth parameter: " + maxDepth);
}
long[] ids = new long[1];
ids[0] = id;
final ThreadInfo[] infos = getThreadInfo(ids, maxDepth);
......@@ -145,11 +144,22 @@ class ThreadImpl implements ThreadMXBean {
return getThreadInfo(ids, 0);
}
public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth) {
private void verifyThreadIds(long[] ids) {
if (ids == null) {
throw new NullPointerException("Null ids parameter.");
}
for (int i = 0; i < ids.length; i++) {
if (ids[i] <= 0) {
throw new IllegalArgumentException(
"Invalid thread ID parameter: " + ids[i]);
}
}
}
public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth) {
verifyThreadIds(ids);
if (maxDepth < 0) {
throw new IllegalArgumentException(
"Invalid maxDepth parameter: " + maxDepth);
......@@ -157,17 +167,15 @@ class ThreadImpl implements ThreadMXBean {
Util.checkMonitorAccess();
ThreadInfo[] infos = new ThreadInfo[ids.length];
ThreadInfo[] infos = new ThreadInfo[ids.length]; // nulls
if (maxDepth == Integer.MAX_VALUE) {
getThreadInfo0(ids, -1, infos);
getThreadInfo1(ids, -1, infos);
} else {
getThreadInfo0(ids, maxDepth, infos);
getThreadInfo1(ids, maxDepth, infos);
}
return infos;
}
public void setThreadContentionMonitoringEnabled(boolean enable) {
if (!isThreadContentionMonitoringSupported()) {
throw new UnsupportedOperationException(
......@@ -192,116 +200,166 @@ class ThreadImpl implements ThreadMXBean {
}
}
public long getCurrentThreadCpuTime() {
private boolean verifyCurrentThreadCpuTime() {
// check if Thread CPU time measurement is supported.
if (!isCurrentThreadCpuTimeSupported()) {
throw new UnsupportedOperationException(
"Current thread CPU time measurement is not supported.");
}
return isThreadCpuTimeEnabled();
}
if (!isThreadCpuTimeEnabled()) {
return -1;
public long getCurrentThreadCpuTime() {
if (verifyCurrentThreadCpuTime()) {
return getThreadTotalCpuTime0(0);
}
return getThreadTotalCpuTime0(0);
return -1;
}
public long getThreadCpuTime(long id) {
long[] ids = new long[1];
ids[0] = id;
final long[] times = getThreadCpuTime(ids);
return times[0];
}
private boolean verifyThreadCpuTime(long[] ids) {
verifyThreadIds(ids);
// check if Thread CPU time measurement is supported.
if (!isThreadCpuTimeSupported() &&
!isCurrentThreadCpuTimeSupported()) {
throw new UnsupportedOperationException(
"Thread CPU Time Measurement is not supported.");
"Thread CPU time measurement is not supported.");
}
if (!isThreadCpuTimeSupported()) {
// support current thread only
if (id != Thread.currentThread().getId()) {
throw new UnsupportedOperationException(
"Thread CPU Time Measurement is only supported" +
" for the current thread.");
for (int i = 0; i < ids.length; i++) {
if (ids[i] != Thread.currentThread().getId()) {
throw new UnsupportedOperationException(
"Thread CPU time measurement is only supported" +
" for the current thread.");
}
}
}
if (id <= 0) {
throw new IllegalArgumentException(
"Invalid thread ID parameter: " + id);
}
return isThreadCpuTimeEnabled();
}
if (!isThreadCpuTimeEnabled()) {
return -1;
}
public long[] getThreadCpuTime(long[] ids) {
boolean verified = verifyThreadCpuTime(ids);
if (id == Thread.currentThread().getId()) {
// current thread
return getThreadTotalCpuTime0(0);
} else {
return getThreadTotalCpuTime0(id);
int length = ids.length;
long[] times = java.util.Arrays.fill(new long[length], -1);
if (verified) {
if (length == 1) {
long id = ids[0];
if (id == Thread.currentThread().getId()) {
id = 0;
}
getThreadTotalCpuTime0(id);
} else {
getThreadTotalCpuTime1(ids, times);
}
}
return times;
}
public long getCurrentThreadUserTime() {
// check if Thread CPU time measurement is supported.
if (!isCurrentThreadCpuTimeSupported()) {
throw new UnsupportedOperationException(
"Current thread CPU time measurement is not supported.");
if (verifyCurrentThreadCpuTime()) {
return getThreadUserCpuTime0(0);
}
return -1;
}
if (!isThreadCpuTimeEnabled()) {
return -1;
}
public long getThreadUserTime(long id) {
long[] ids = new long[1];
ids[0] = id;
final long[] times = getThreadUserTime(ids);
return times[0];
}
return getThreadUserCpuTime0(0);
public long[] getThreadUserTime(long[] ids) {
boolean verified = verifyThreadCpuTime(ids);
int length = ids.length;
long[] times = java.util.Arrays.fill(new long[length], -1);
if (verified) {
if (length == 1) {
long id = ids[0];
if (id == Thread.currentThread().getId()) {
id = 0;
}
times[0] = getThreadUserCpuTime0(id);
} else {
getThreadUserCpuTime1(ids, times);
}
}
return times;
}
public long getThreadUserTime(long id) {
// check if Thread CPU time measurement is supported.
public void setThreadCpuTimeEnabled(boolean enable) {
if (!isThreadCpuTimeSupported() &&
!isCurrentThreadCpuTimeSupported()) {
throw new UnsupportedOperationException(
"Thread CPU time measurement is not supported.");
"Thread CPU time measurement is not supported");
}
if (!isThreadCpuTimeSupported()) {
// support current thread only
if (id != Thread.currentThread().getId()) {
throw new UnsupportedOperationException(
"Thread CPU time measurement is only supported" +
" for the current thread.");
Util.checkControlAccess();
synchronized (this) {
if (cpuTimeEnabled != enable) {
// notify VM of the state change
setThreadCpuTimeEnabled0(enable);
cpuTimeEnabled = enable;
}
}
}
if (id <= 0) {
throw new IllegalArgumentException(
"Invalid thread ID parameter: " + id);
}
public long getThreadAllocatedBytes(long id) {
long[] ids = new long[1];
ids[0] = id;
final long[] sizes = getThreadAllocatedBytes(ids);
return sizes[0];
}
if (!isThreadCpuTimeEnabled()) {
return -1;
}
private boolean verifyThreadAllocatedMemory(long[] ids) {
verifyThreadIds(ids);
if (id == Thread.currentThread().getId()) {
// current thread
return getThreadUserCpuTime0(0);
} else {
return getThreadUserCpuTime0(id);
// check if Thread allocated memory measurement is supported.
if (!isThreadAllocatedMemorySupported()) {
throw new UnsupportedOperationException(
"Thread allocated memory measurement is not supported.");
}
return isThreadAllocatedMemoryEnabled();
}
public long[] getThreadAllocatedBytes(long[] ids) {
boolean verified = verifyThreadAllocatedMemory(ids);
public void setThreadCpuTimeEnabled(boolean enable) {
if (!isThreadCpuTimeSupported() &&
!isCurrentThreadCpuTimeSupported()) {
long[] times = java.util.Arrays.fill(new long[length], -1);
if (verified) {
getThreadAllocatedMemory1(ids, sizes);
}
return sizes;
}
public void setThreadAllocatedMemoryEnabled(boolean enable) {
if (!isThreadAllocatedMemorySupported()) {
throw new UnsupportedOperationException(
"Thread CPU time measurement is not supported");
"Thread allocated memory measurement is not supported.");
}
Util.checkControlAccess();
synchronized (this) {
if (cpuTimeEnabled != enable) {
// update VM of the state change
setThreadCpuTimeEnabled0(enable);
cpuTimeEnabled = enable;
if (allocatedMemoryEnabled != enable) {
// notify VM of the state change
setThreadAllocatedMemoryEnabled0(enable);
allocatedMemoryEnabled = enable;
}
}
}
......@@ -356,49 +414,47 @@ class ThreadImpl implements ThreadMXBean {
return jvm.isSynchronizerUsageSupported();
}
public ThreadInfo[] getThreadInfo(long[] ids,
boolean lockedMonitors,
boolean lockedSynchronizers) {
if (ids == null) {
throw new NullPointerException("Null ids parameter.");
}
private void verifyDumpThreads(boolean lockedMonitors,
boolean lockedSynchronizers) {
if (lockedMonitors && !isObjectMonitorUsageSupported()) {
throw new UnsupportedOperationException(
"Monitoring of Object Monitor Usage is not supported.");
}
if (lockedSynchronizers && !isSynchronizerUsageSupported()) {
throw new UnsupportedOperationException(
"Monitoring of Synchronizer Usage is not supported.");
}
Util.checkMonitorAccess();
return dumpThreads0(ids, lockedMonitors, lockedSynchronizers);
}
public ThreadInfo[] getThreadInfo(long[] ids,
boolean lockedMonitors,
boolean lockedSynchronizers) {
verifyThreadIds(ids);
verifyDumpThreads(lockedMonitors, lockedSynchronizers);
return dumpThreads0(ids, lockedMonitors, lockedSynchronizers);
}
public ThreadInfo[] dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers) {
if (lockedMonitors && !isObjectMonitorUsageSupported()) {
throw new UnsupportedOperationException(
"Monitoring of Object Monitor Usage is not supported.");
}
if (lockedSynchronizers && !isSynchronizerUsageSupported()) {
throw new UnsupportedOperationException(
"Monitoring of Synchronizer Usage is not supported.");
}
Util.checkMonitorAccess();
public ThreadInfo[] dumpAllThreads(boolean lockedMonitors,
boolean lockedSynchronizers) {
verifyDumpThreads(lockedMonitors, lockedSynchronizers);
return dumpThreads0(null, lockedMonitors, lockedSynchronizers);
}
// VM support where maxDepth == -1 to request entire stack dump
private static native Thread[] getThreads();
private static native void getThreadInfo0(long[] ids,
private static native void getThreadInfo1(long[] ids,
int maxDepth,
ThreadInfo[] result);
private static native long getThreadTotalCpuTime0(long id);
private static native void getThreadTotalCpuTime1(long[] ids, long[] result);
private static native long getThreadUserCpuTime0(long id);
private static native void getThreadUserCpuTime1(long[] ids, long[] result);
private static native void getThreadAllocatedMemory1(long[] ids, long[] result);
private static native void setThreadCpuTimeEnabled0(boolean enable);
private static native void setThreadAllocatedMemoryEnabled0(boolean enable);
private static native void setThreadContentionMonitoringEnabled0(boolean enable);
private static native Thread[] findMonitorDeadlockedThreads0();
private static native Thread[] findDeadlockedThreads0();
......
/*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -43,6 +43,8 @@ public interface VMManagement {
public boolean isBootClassPathSupported();
public boolean isObjectMonitorUsageSupported();
public boolean isSynchronizerUsageSupported();
public boolean isThreadAllocatedMemorySupported();
public boolean isThreadAllocatedMemoryEnabled();
// Class Loading Subsystem
public long getTotalClassCount();
......
/*
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -55,6 +55,7 @@ class VMManagementImpl implements VMManagement {
private static boolean bootClassPathSupport;
private static boolean objectMonitorUsageSupport;
private static boolean synchronizerUsageSupport;
private static boolean threadAllocatedMemorySupport;
static {
version = getVersion0();
......@@ -95,9 +96,13 @@ class VMManagementImpl implements VMManagement {
return synchronizerUsageSupport;
}
public boolean isThreadAllocatedMemorySupported() {
return threadAllocatedMemorySupport;
}
public native boolean isThreadContentionMonitoringEnabled();
public native boolean isThreadCpuTimeEnabled();
public native boolean isThreadAllocatedMemoryEnabled();
// Class Loading Subsystem
public int getLoadedClassCount() {
......
/*
* Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -60,7 +60,8 @@ typedef struct {
unsigned int isBootClassPathSupported : 1;
unsigned int isObjectMonitorUsageSupported : 1;
unsigned int isSynchronizerUsageSupported : 1;
unsigned int : 24;
unsigned int isThreadAllocatedMemorySupported : 1;
unsigned int : 23;
} jmmOptionalSupport;
typedef enum {
......@@ -105,7 +106,8 @@ typedef enum {
JMM_VERBOSE_GC = 21,
JMM_VERBOSE_CLASS = 22,
JMM_THREAD_CONTENTION_MONITORING = 23,
JMM_THREAD_CPU_TIME = 24
JMM_THREAD_CPU_TIME = 24,
JMM_THREAD_ALLOCATED_MEMORY = 25
} jmmBoolAttribute;
......@@ -213,7 +215,10 @@ typedef struct jmmInterface_1_ {
jobject (JNICALL *GetMemoryPoolUsage) (JNIEnv* env, jobject pool);
jobject (JNICALL *GetPeakMemoryPoolUsage) (JNIEnv* env, jobject pool);
void* reserved4;
void (JNICALL *GetThreadAllocatedMemory)
(JNIEnv *env,
jlongArray ids,
jlongArray sizeArray);
jobject (JNICALL *GetMemoryUsage) (JNIEnv* env, jboolean heap);
......@@ -228,6 +233,8 @@ typedef struct jmmInterface_1_ {
jlong* result);
jobjectArray (JNICALL *FindCircularBlockedThreads) (JNIEnv *env);
// Not used in JDK 6 or JDK 7
jlong (JNICALL *GetThreadCpuTime) (JNIEnv *env, jlong thread_id);
jobjectArray (JNICALL *GetVMGlobalNames) (JNIEnv *env);
......@@ -262,14 +269,22 @@ typedef struct jmmInterface_1_ {
void (JNICALL *GetLastGCStat) (JNIEnv *env,
jobject mgr,
jmmGCStat *gc_stat);
jlong (JNICALL *GetThreadCpuTimeWithKind) (JNIEnv *env,
jlong thread_id,
jboolean user_sys_cpu_time);
void* reserved5;
jlong (JNICALL *GetThreadCpuTimeWithKind)
(JNIEnv *env,
jlong thread_id,
jboolean user_sys_cpu_time);
void (JNICALL *GetThreadCpuTimesWithKind)
(JNIEnv *env,
jlongArray ids,
jlongArray timeArray,
jboolean user_sys_cpu_time);
jint (JNICALL *DumpHeap0) (JNIEnv *env,
jstring outputfile,
jboolean live);
jobjectArray (JNICALL *FindDeadlocks) (JNIEnv *env, jboolean object_monitors_only);
jobjectArray (JNICALL *FindDeadlocks) (JNIEnv *env,
jboolean object_monitors_only);
void (JNICALL *SetVMGlobal) (JNIEnv *env,
jstring flag_name,
jvalue new_value);
......
/*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -42,9 +42,15 @@ Java_sun_management_ThreadImpl_setThreadCpuTimeEnabled0
jmm_interface->SetBoolAttribute(env, JMM_THREAD_CPU_TIME, flag);
}
JNIEXPORT void JNICALL
Java_sun_management_ThreadImpl_setThreadAllocatedMemoryEnabled0
(JNIEnv *env, jclass cls, jboolean flag)
{
jmm_interface->SetBoolAttribute(env, JMM_THREAD_ALLOCATED_MEMORY, flag);
}
JNIEXPORT void JNICALL
Java_sun_management_ThreadImpl_getThreadInfo0
Java_sun_management_ThreadImpl_getThreadInfo1
(JNIEnv *env, jclass cls, jlongArray ids, jint maxDepth,
jobjectArray infoArray)
{
......@@ -65,6 +71,14 @@ Java_sun_management_ThreadImpl_getThreadTotalCpuTime0
return jmm_interface->GetThreadCpuTimeWithKind(env, tid, JNI_TRUE /* user+sys */);
}
JNIEXPORT void JNICALL
Java_sun_management_ThreadImpl_getThreadTotalCpuTime1
(JNIEnv *env, jclass cls, jlongArray ids, jlongArray timeArray)
{
jmm_interface->GetThreadCpuTimesWithKind(env, ids, timeArray,
JNI_TRUE /* user+sys */);
}
JNIEXPORT jlong JNICALL
Java_sun_management_ThreadImpl_getThreadUserCpuTime0
(JNIEnv *env, jclass cls, jlong tid)
......@@ -72,6 +86,21 @@ Java_sun_management_ThreadImpl_getThreadUserCpuTime0
return jmm_interface->GetThreadCpuTimeWithKind(env, tid, JNI_FALSE /* user */);
}
JNIEXPORT void JNICALL
Java_sun_management_ThreadImpl_getThreadUserCpuTime1
(JNIEnv *env, jclass cls, jlongArray ids, jlongArray timeArray)
{
jmm_interface->GetThreadCpuTimesWithKind(env, ids, timeArray,
JNI_FALSE /* user */);
}
JNIEXPORT void JNICALL
Java_sun_management_ThreadImpl_getThreadAllocatedMemory1
(JNIEnv *env, jclass cls, jlongArray ids, jlongArray sizeArray)
{
jmm_interface->GetThreadAllocatedMemory(env, ids, sizeArray);
}
JNIEXPORT jobjectArray JNICALL
Java_sun_management_ThreadImpl_findMonitorDeadlockedThreads0
(JNIEnv *env, jclass cls)
......
/*
* Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -92,6 +92,9 @@ Java_sun_management_VMManagementImpl_initOptionalSupportFields
setStaticBooleanField(env, cls, "objectMonitorUsageSupport", JNI_FALSE);
setStaticBooleanField(env, cls, "synchronizerUsageSupport", JNI_FALSE);
}
value = mos.isThreadAllocatedMemorySupported;
setStaticBooleanField(env, cls, "threadAllocatedMemorySupport", value);
}
JNIEXPORT jobjectArray JNICALL
......@@ -201,6 +204,13 @@ Java_sun_management_VMManagementImpl_isThreadCpuTimeEnabled
return jmm_interface->GetBoolAttribute(env, JMM_THREAD_CPU_TIME);
}
JNIEXPORT jboolean JNICALL
Java_sun_management_VMManagementImpl_isThreadAllocatedMemoryEnabled
(JNIEnv *env, jobject dummy)
{
return jmm_interface->GetBoolAttribute(env, JMM_THREAD_ALLOCATED_MEMORY);
}
JNIEXPORT jint JNICALL
Java_sun_management_VMManagementImpl_getProcessId
(JNIEnv *env, jobject dummy)
......
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6173675
* @summary Basic test of ThreadMXBean.getThreadAllocatedBytes
* @author Paul Hohensee
*/
import java.lang.management.*;
public class ThreadAllocatedMemory {
private static com.sun.management.ThreadMXBean mbean =
(com.sun.management.ThreadMXBean)ManagementFactory.getThreadMXBean();
private static boolean testFailed = false;
private static boolean done = false;
private static boolean done1 = false;
private static Object obj = new Object();
private static final int NUM_THREADS = 10;
private static Thread[] threads = new Thread[NUM_THREADS];
private static long[] sizes = new long[NUM_THREADS];
public static void main(String[] argv)
throws Exception {
if (!mbean.isThreadAllocatedMemorySupported()) {
return;
}
// disable allocated memory measurement
if (mbean.isThreadAllocatedMemoryEnabled()) {
mbean.setThreadAllocatedMemoryEnabled(false);
}
if (mbean.isThreadAllocatedMemoryEnabled()) {
throw new RuntimeException(
"ThreadAllocatedMemory is expected to be disabled");
}
Thread curThread = Thread.currentThread();
long id = curThread.getId();
long s = mbean.getThreadAllocatedBytes(id);
if (s != -1) {
throw new RuntimeException(
"Invalid ThreadAllocatedBytes returned = " +
s + " expected = -1");
}
// enable allocated memory measurement
if (!mbean.isThreadAllocatedMemoryEnabled()) {
mbean.setThreadAllocatedMemoryEnabled(true);
}
if (!mbean.isThreadAllocatedMemoryEnabled()) {
throw new RuntimeException(
"ThreadAllocatedMemory is expected to be enabled");
}
long size = mbean.getThreadAllocatedBytes(id);
// implementation could have started measurement when
// measurement was enabled, in which case size can be 0
if (size < 0) {
throw new RuntimeException(
"Invalid allocated bytes returned = " + size);
}
doit();
// Expected to be size1 >= size
long size1 = mbean.getThreadAllocatedBytes(id);
if (size1 < size) {
throw new RuntimeException("Allocated bytes " + size1 +
" expected >= " + size);
}
System.out.println(curThread.getName() +
" Current thread allocated bytes = " + size +
" allocated bytes = " + size1);
// start threads, wait for them to block
for (int i = 0; i < NUM_THREADS; i++) {
threads[i] = new MyThread("MyThread-" + i);
threads[i].start();
}
// threads block after doing some allocation
waitUntilThreadBlocked();
for (int i = 0; i < NUM_THREADS; i++) {
sizes[i] = mbean.getThreadAllocatedBytes(threads[i].getId());
}
// let threads go and do some more allocation
synchronized (obj) {
done = true;
obj.notifyAll();
}
// wait for threads to get going again. we don't care if we
// catch them in mid-execution or if some of them haven't
// restarted after we're done sleeping.
goSleep(400);
for (int i = 0; i < NUM_THREADS; i++) {
long newSize = mbean.getThreadAllocatedBytes(threads[i].getId());
if (sizes[i] > newSize) {
throw new RuntimeException("TEST FAILED: " +
threads[i].getName() +
" previous allocated bytes = " + sizes[i] +
" > current allocated bytes = " + newSize);
}
System.out.println(threads[i].getName() +
" Previous allocated bytes = " + sizes[i] +
" Current allocated bytes = " + newSize);
}
// let threads exit
synchronized (obj) {
done1 = true;
obj.notifyAll();
}
for (int i = 0; i < NUM_THREADS; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
e.printStackTrace(System.out);
testFailed = true;
break;
}
}
if (testFailed) {
throw new RuntimeException("TEST FAILED");
}
System.out.println("Test passed");
}
private static void goSleep(long ms) throws Exception {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
throw e;
}
}
private static void waitUntilThreadBlocked()
throws Exception {
int count = 0;
while (count != NUM_THREADS) {
goSleep(100);
count = 0;
for (int i = 0; i < NUM_THREADS; i++) {
ThreadInfo info = mbean.getThreadInfo(threads[i].getId());
if (info.getThreadState() == Thread.State.WAITING) {
count++;
}
}
}
}
public static void doit() {
String tmp = "";
long hashCode = 0;
for (int counter = 0; counter < 1000; counter++) {
tmp += counter;
hashCode = tmp.hashCode();
}
System.out.println(Thread.currentThread().getName() +
" hashcode: " + hashCode);
}
static class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
public void run() {
ThreadAllocatedMemory.doit();
synchronized (obj) {
while (!done) {
try {
obj.wait();
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
e.printStackTrace(System.out);
testFailed = true;
break;
}
}
}
long size1 = mbean.getThreadAllocatedBytes(getId());
ThreadAllocatedMemory.doit();
long size2 = mbean.getThreadAllocatedBytes(getId());
System.out.println(getName() + ": " +
"ThreadAllocatedBytes = " + size1 +
" ThreadAllocatedBytes = " + size2);
if (size1 > size2) {
throw new RuntimeException("TEST FAILED: " + getName() +
" ThreadAllocatedBytes = " + size1 +
" > ThreadAllocatedBytes = " + size2);
}
synchronized (obj) {
while (!done1) {
try {
obj.wait();
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
e.printStackTrace(System.out);
testFailed = true;
break;
}
}
}
}
}
}
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6173675
* @summary Basic test of ThreadMXBean.getThreadAllocatedBytes(long[])
* @author Paul Hohensee
*/
import java.lang.management.*;
public class ThreadAllocatedMemoryArray {
private static com.sun.management.ThreadMXBean mbean =
(com.sun.management.ThreadMXBean)ManagementFactory.getThreadMXBean();
private static boolean testFailed = false;
private static boolean done = false;
private static boolean done1 = false;
private static Object obj = new Object();
private static final int NUM_THREADS = 10;
private static Thread[] threads = new Thread[NUM_THREADS];
public static void main(String[] argv)
throws Exception {
if (!mbean.isThreadAllocatedMemorySupported()) {
return;
}
// start threads, wait for them to block
long[] ids = new long[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
threads[i] = new MyThread("MyThread-" + i);
threads[i].start();
ids[i] = threads[i].getId();
}
waitUntilThreadBlocked();
// disable allocated memory measurement
if (mbean.isThreadAllocatedMemoryEnabled()) {
mbean.setThreadAllocatedMemoryEnabled(false);
}
if (mbean.isThreadAllocatedMemoryEnabled()) {
throw new RuntimeException(
"ThreadAllocatedMemory is expected to be disabled");
}
long sizes[] = mbean.getThreadAllocatedBytes(ids);
if (sizes == null) {
throw new RuntimeException("Null ThreadAllocatedBytes array returned");
}
for (int i = 0; i < NUM_THREADS; i++) {
long s = sizes[i];
if (s != -1) {
throw new RuntimeException(
"Invalid ThreadAllocatedBytes returned for thread " +
threads[i].getName() + " = " + s + " expected = -1");
}
}
// Enable allocated memory measurement
if (!mbean.isThreadAllocatedMemoryEnabled()) {
mbean.setThreadAllocatedMemoryEnabled(true);
}
if (!mbean.isThreadAllocatedMemoryEnabled()) {
throw new RuntimeException(
"ThreadAllocatedMemory is expected to be enabled");
}
sizes = mbean.getThreadAllocatedBytes(ids);
for (int i = 0; i < NUM_THREADS; i++) {
long s = sizes[i];
if (s < 0) {
throw new RuntimeException(
"Invalid allocated bytes returned for thread " +
threads[i].getName() + " = " + s);
}
}
// let threads go and do some more allocation
synchronized (obj) {
done = true;
obj.notifyAll();
}
// wait for threads to get going again. we don't care if we
// catch them in mid-execution or if some of them haven't
// restarted after we're done sleeping.
goSleep(400);
long[] sizes1 = mbean.getThreadAllocatedBytes(ids);
for (int i = 0; i < NUM_THREADS; i++) {
long newSize = sizes1[i];
if (sizes[i] > newSize) {
throw new RuntimeException("TEST FAILED: " +
threads[i].getName() +
" previous allocated bytes = " + sizes[i] +
" > current allocated bytes = " + newSize);
}
System.out.println(threads[i].getName() +
" Previous allocated bytes = " + sizes[i] +
" Current allocated bytes = " + newSize);
}
try {
sizes = mbean.getThreadAllocatedBytes(null);
} catch (NullPointerException e) {
System.out.println(
"Caught expected NullPointerException: " + e.getMessage());
}
try {
ids[0] = 0;
sizes = mbean.getThreadAllocatedBytes(ids);
} catch (IllegalArgumentException e) {
System.out.println(
"Caught expected IllegalArgumentException: " + e.getMessage());
}
// let threads exit
synchronized (obj) {
done1 = true;
obj.notifyAll();
}
for (int i = 0; i < NUM_THREADS; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
e.printStackTrace(System.out);
testFailed = true;
break;
}
}
if (testFailed) {
throw new RuntimeException("TEST FAILED");
}
System.out.println("Test passed");
}
private static void goSleep(long ms) throws Exception {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
throw e;
}
}
private static void waitUntilThreadBlocked()
throws Exception {
int count = 0;
while (count != NUM_THREADS) {
goSleep(100);
count = 0;
for (int i = 0; i < NUM_THREADS; i++) {
ThreadInfo info = mbean.getThreadInfo(threads[i].getId());
if (info.getThreadState() == Thread.State.WAITING) {
count++;
}
}
}
}
public static void doit() {
String tmp = "";
long hashCode = 0;
for (int counter = 0; counter < 1000; counter++) {
tmp += counter;
hashCode = tmp.hashCode();
}
System.out.println(Thread.currentThread().getName() +
" hashcode: " + hashCode);
}
static class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
public void run() {
ThreadAllocatedMemoryArray.doit();
synchronized (obj) {
while (!done) {
try {
obj.wait();
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
e.printStackTrace(System.out);
testFailed = true;
break;
}
}
}
ThreadAllocatedMemoryArray.doit();
synchronized (obj) {
while (!done1) {
try {
obj.wait();
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
e.printStackTrace(System.out);
testFailed = true;
break;
}
}
}
}
}
}
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6173675
* @summary Basic test of ThreadMXBean.getThreadCpuTime(long[]) and
* getThreadUserTime(long[]).
* @author Paul Hohensee
*/
import java.lang.management.*;
public class ThreadCpuTimeArray {
private static com.sun.management.ThreadMXBean mbean =
(com.sun.management.ThreadMXBean)ManagementFactory.getThreadMXBean();
private static boolean testFailed = false;
private static boolean done = false;
private static Object obj = new Object();
private static final int NUM_THREADS = 10;
private static Thread[] threads = new Thread[NUM_THREADS];
// careful about this value
private static final int DELTA = 100;
public static void main(String[] argv)
throws Exception {
if (!mbean.isThreadCpuTimeSupported()) {
return;
}
// disable CPU time
if (mbean.isThreadCpuTimeEnabled()) {
mbean.setThreadCpuTimeEnabled(false);
}
if (mbean.isThreadCpuTimeEnabled()) {
throw new RuntimeException("ThreadCpuTime is expected to be disabled");
}
// start threads, wait for them to block
long[] ids = new long[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
threads[i] = new MyThread("MyThread-" + i);
threads[i].start();
ids[i] = threads[i].getId();
}
// threads block after doing some computation
waitUntilThreadBlocked();
long times[] = mbean.getThreadCpuTime(ids);
long userTimes[] = mbean.getThreadUserTime(ids);
if (times == null) {
throw new RuntimeException("Null ThreadCpuTime array returned");
}
for (int i = 0; i < NUM_THREADS; i++) {
long t = times[i];
if (t != -1) {
throw new RuntimeException(
"Invalid ThreadCpuTime returned for thread " +
threads[i].getName() + " = " + t + " expected = -1");
}
long ut = userTimes[i];
if (ut != -1) {
throw new RuntimeException(
"Invalid ThreadUserTime returned for thread " +
threads[i].getName() + " = " + ut + " expected = -1");
}
}
// Enable CPU Time measurement
if (!mbean.isThreadCpuTimeEnabled()) {
mbean.setThreadCpuTimeEnabled(true);
}
if (!mbean.isThreadCpuTimeEnabled()) {
throw new RuntimeException("ThreadCpuTime is expected to be enabled");
}
times = mbean.getThreadCpuTime(ids);
userTimes = mbean.getThreadUserTime(ids);
goSleep(200);
for (int i = 0; i < NUM_THREADS; i++) {
long t = times[i];
if (t < 0) {
throw new RuntimeException(
"Invalid CPU time returned for thread " +
threads[i].getName() + " = " + t);
}
long ut = userTimes[i];
if (ut < 0) {
throw new RuntimeException(
"Invalid user time returned for thread " +
threads[i].getName() + " = " + ut);
}
}
long[] times1 = mbean.getThreadCpuTime(ids);
long[] userTimes1 = mbean.getThreadUserTime(ids);
for (int i = 0; i < NUM_THREADS; i++) {
long newTime = times1[i];
long newUserTime = userTimes1[i];
if (times[i] > newTime) {
throw new RuntimeException("TEST FAILED: " +
threads[i].getName() +
" previous CPU time = " + times[i] +
" > current CPU time = " + newTime);
}
if ((times[i] + DELTA) < newTime) {
throw new RuntimeException("TEST FAILED: " +
threads[i].getName() +
" CPU time = " + newTime +
" previous CPU time " + times[i] +
" out of expected range");
}
System.out.println(threads[i].getName() +
" Previous Cpu Time = " + times[i] +
" Current CPU time = " + newTime);
System.out.println(threads[i].getName() +
" Previous User Time = " + userTimes[i] +
" Current User time = " + newUserTime);
}
try {
times = mbean.getThreadCpuTime(null);
} catch (NullPointerException e) {
System.out.println(
"Caught expected NullPointerException: " + e.getMessage());
}
try {
ids[0] = 0;
times = mbean.getThreadCpuTime(ids);
} catch (IllegalArgumentException e) {
System.out.println(
"Caught expected IllegalArgumentException: " + e.getMessage());
}
// let threads exit
synchronized (obj) {
done = true;
obj.notifyAll();
}
for (int i = 0; i < NUM_THREADS; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
e.printStackTrace(System.out);
testFailed = true;
break;
}
}
if (testFailed) {
throw new RuntimeException("TEST FAILED");
}
System.out.println("Test passed");
}
private static void goSleep(long ms) throws Exception {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
throw e;
}
}
private static void waitUntilThreadBlocked()
throws Exception {
int count = 0;
while (count != NUM_THREADS) {
goSleep(100);
count = 0;
for (int i = 0; i < NUM_THREADS; i++) {
ThreadInfo info = mbean.getThreadInfo(threads[i].getId());
if (info.getThreadState() == Thread.State.WAITING) {
count++;
}
}
}
}
public static void doit() {
double sum = 0;
for (int i = 0; i < 5000; i++) {
double r = Math.random();
double x = Math.pow(3, r);
sum += x - r;
}
System.out.println(Thread.currentThread().getName() +
" sum = " + sum);
}
static class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
public void run() {
ThreadCpuTimeArray.doit();
synchronized (obj) {
while (!done) {
try {
obj.wait();
} catch (InterruptedException e) {
System.out.println("Unexpected exception is thrown.");
e.printStackTrace(System.out);
testFailed = true;
break;
}
}
}
ThreadCpuTimeArray.doit();
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册