6173675: M&M: approximate memory allocation rate/amount per thread
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
This commit is contained in:
parent
5eb8f2a9ef
commit
c37b51609d
@ -1,5 +1,5 @@
|
||||
#
|
||||
# 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:
|
||||
*;
|
||||
|
221
jdk/src/share/classes/com/sun/management/ThreadMXBean.java
Normal file
221
jdk/src/share/classes/com/sun/management/ThreadMXBean.java
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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,69 +200,32 @@ 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) {
|
||||
// check if Thread CPU time measurement is supported.
|
||||
if (!isThreadCpuTimeSupported() &&
|
||||
!isCurrentThreadCpuTimeSupported()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"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.");
|
||||
}
|
||||
}
|
||||
|
||||
if (id <= 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid thread ID parameter: " + id);
|
||||
}
|
||||
|
||||
if (!isThreadCpuTimeEnabled()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (id == Thread.currentThread().getId()) {
|
||||
// current thread
|
||||
return getThreadTotalCpuTime0(0);
|
||||
} else {
|
||||
return getThreadTotalCpuTime0(id);
|
||||
}
|
||||
long[] ids = new long[1];
|
||||
ids[0] = id;
|
||||
final long[] times = getThreadCpuTime(ids);
|
||||
return times[0];
|
||||
}
|
||||
|
||||
public long getCurrentThreadUserTime() {
|
||||
// check if Thread CPU time measurement is supported.
|
||||
if (!isCurrentThreadCpuTimeSupported()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Current thread CPU time measurement is not supported.");
|
||||
}
|
||||
private boolean verifyThreadCpuTime(long[] ids) {
|
||||
verifyThreadIds(ids);
|
||||
|
||||
if (!isThreadCpuTimeEnabled()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return getThreadUserCpuTime0(0);
|
||||
}
|
||||
|
||||
public long getThreadUserTime(long id) {
|
||||
// check if Thread CPU time measurement is supported.
|
||||
if (!isThreadCpuTimeSupported() &&
|
||||
!isCurrentThreadCpuTimeSupported()) {
|
||||
@ -264,30 +235,71 @@ class ThreadImpl implements ThreadMXBean {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (!isThreadCpuTimeEnabled()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (id == Thread.currentThread().getId()) {
|
||||
// current thread
|
||||
return getThreadUserCpuTime0(0);
|
||||
} else {
|
||||
return getThreadUserCpuTime0(id);
|
||||
}
|
||||
return isThreadCpuTimeEnabled();
|
||||
}
|
||||
|
||||
public long[] getThreadCpuTime(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;
|
||||
}
|
||||
getThreadTotalCpuTime0(id);
|
||||
} else {
|
||||
getThreadTotalCpuTime1(ids, times);
|
||||
}
|
||||
}
|
||||
return times;
|
||||
}
|
||||
|
||||
public long getCurrentThreadUserTime() {
|
||||
if (verifyCurrentThreadCpuTime()) {
|
||||
return getThreadUserCpuTime0(0);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public long getThreadUserTime(long id) {
|
||||
long[] ids = new long[1];
|
||||
ids[0] = id;
|
||||
final long[] times = getThreadUserTime(ids);
|
||||
return times[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 void setThreadCpuTimeEnabled(boolean enable) {
|
||||
if (!isThreadCpuTimeSupported() &&
|
||||
@ -299,13 +311,59 @@ class ThreadImpl implements ThreadMXBean {
|
||||
Util.checkControlAccess();
|
||||
synchronized (this) {
|
||||
if (cpuTimeEnabled != enable) {
|
||||
// update VM of the state change
|
||||
// notify VM of the state change
|
||||
setThreadCpuTimeEnabled0(enable);
|
||||
cpuTimeEnabled = enable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long getThreadAllocatedBytes(long id) {
|
||||
long[] ids = new long[1];
|
||||
ids[0] = id;
|
||||
final long[] sizes = getThreadAllocatedBytes(ids);
|
||||
return sizes[0];
|
||||
}
|
||||
|
||||
private boolean verifyThreadAllocatedMemory(long[] ids) {
|
||||
verifyThreadIds(ids);
|
||||
|
||||
// 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);
|
||||
|
||||
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 allocated memory measurement is not supported.");
|
||||
}
|
||||
|
||||
Util.checkControlAccess();
|
||||
synchronized (this) {
|
||||
if (allocatedMemoryEnabled != enable) {
|
||||
// notify VM of the state change
|
||||
setThreadAllocatedMemoryEnabled0(enable);
|
||||
allocatedMemoryEnabled = enable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long[] findMonitorDeadlockedThreads() {
|
||||
Util.checkMonitorAccess();
|
||||
|
||||
@ -356,49 +414,47 @@ class ThreadImpl implements ThreadMXBean {
|
||||
return jvm.isSynchronizerUsageSupported();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
public ThreadInfo[] getThreadInfo(long[] ids,
|
||||
boolean lockedMonitors,
|
||||
boolean lockedSynchronizers) {
|
||||
if (ids == null) {
|
||||
throw new NullPointerException("Null ids parameter.");
|
||||
}
|
||||
|
||||
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();
|
||||
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();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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)
|
||||
|
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
259
jdk/test/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java
Normal file
259
jdk/test/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user