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.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# 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_dumpThreads0;
|
||||||
Java_sun_management_ThreadImpl_findDeadlockedThreads0;
|
Java_sun_management_ThreadImpl_findDeadlockedThreads0;
|
||||||
Java_sun_management_ThreadImpl_findMonitorDeadlockedThreads0;
|
Java_sun_management_ThreadImpl_findMonitorDeadlockedThreads0;
|
||||||
Java_sun_management_ThreadImpl_getThreadInfo0;
|
Java_sun_management_ThreadImpl_getThreadInfo1;
|
||||||
Java_sun_management_ThreadImpl_getThreads;
|
Java_sun_management_ThreadImpl_getThreads;
|
||||||
Java_sun_management_ThreadImpl_getThreadTotalCpuTime0;
|
Java_sun_management_ThreadImpl_getThreadTotalCpuTime0;
|
||||||
|
Java_sun_management_ThreadImpl_getThreadTotalCpuTime1;
|
||||||
Java_sun_management_ThreadImpl_getThreadUserCpuTime0;
|
Java_sun_management_ThreadImpl_getThreadUserCpuTime0;
|
||||||
|
Java_sun_management_ThreadImpl_getThreadUserCpuTime1;
|
||||||
|
Java_sun_management_ThreadImpl_getThreadAllocatedMemory1;
|
||||||
Java_sun_management_ThreadImpl_resetContentionTimes0;
|
Java_sun_management_ThreadImpl_resetContentionTimes0;
|
||||||
Java_sun_management_ThreadImpl_resetPeakThreadCount0;
|
Java_sun_management_ThreadImpl_resetPeakThreadCount0;
|
||||||
Java_sun_management_ThreadImpl_setThreadContentionMonitoringEnabled0;
|
Java_sun_management_ThreadImpl_setThreadContentionMonitoringEnabled0;
|
||||||
Java_sun_management_ThreadImpl_setThreadCpuTimeEnabled0;
|
Java_sun_management_ThreadImpl_setThreadCpuTimeEnabled0;
|
||||||
|
Java_sun_management_ThreadImpl_setThreadAllocatedMemoryEnabled0;
|
||||||
Java_sun_management_VMManagementImpl_getAvailableProcessors;
|
Java_sun_management_VMManagementImpl_getAvailableProcessors;
|
||||||
Java_sun_management_VMManagementImpl_getClassInitializationTime;
|
Java_sun_management_VMManagementImpl_getClassInitializationTime;
|
||||||
Java_sun_management_VMManagementImpl_getClassLoadingTime;
|
Java_sun_management_VMManagementImpl_getClassLoadingTime;
|
||||||
@ -106,6 +110,7 @@ SUNWprivate_1.1 {
|
|||||||
Java_sun_management_VMManagementImpl_initOptionalSupportFields;
|
Java_sun_management_VMManagementImpl_initOptionalSupportFields;
|
||||||
Java_sun_management_VMManagementImpl_isThreadContentionMonitoringEnabled;
|
Java_sun_management_VMManagementImpl_isThreadContentionMonitoringEnabled;
|
||||||
Java_sun_management_VMManagementImpl_isThreadCpuTimeEnabled;
|
Java_sun_management_VMManagementImpl_isThreadCpuTimeEnabled;
|
||||||
|
Java_sun_management_VMManagementImpl_isThreadAllocatedMemoryEnabled;
|
||||||
JNI_OnLoad;
|
JNI_OnLoad;
|
||||||
local:
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
package sun.management;
|
package sun.management;
|
||||||
|
|
||||||
import java.lang.management.ThreadMXBean;
|
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
|
|
||||||
import java.lang.management.ThreadInfo;
|
import java.lang.management.ThreadInfo;
|
||||||
@ -39,13 +38,14 @@ import javax.management.ObjectName;
|
|||||||
* ManagementFactory.getThreadMXBean() returns an instance
|
* ManagementFactory.getThreadMXBean() returns an instance
|
||||||
* of this class.
|
* of this class.
|
||||||
*/
|
*/
|
||||||
class ThreadImpl implements ThreadMXBean {
|
class ThreadImpl implements com.sun.management.ThreadMXBean {
|
||||||
|
|
||||||
private final VMManagement jvm;
|
private final VMManagement jvm;
|
||||||
|
|
||||||
// default for thread contention monitoring is disabled.
|
// default for thread contention monitoring is disabled.
|
||||||
private boolean contentionMonitoringEnabled = false;
|
private boolean contentionMonitoringEnabled = false;
|
||||||
private boolean cpuTimeEnabled;
|
private boolean cpuTimeEnabled;
|
||||||
|
private boolean allocatedMemoryEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor of ThreadImpl class.
|
* Constructor of ThreadImpl class.
|
||||||
@ -53,6 +53,7 @@ class ThreadImpl implements ThreadMXBean {
|
|||||||
ThreadImpl(VMManagement vm) {
|
ThreadImpl(VMManagement vm) {
|
||||||
this.jvm = vm;
|
this.jvm = vm;
|
||||||
this.cpuTimeEnabled = jvm.isThreadCpuTimeEnabled();
|
this.cpuTimeEnabled = jvm.isThreadCpuTimeEnabled();
|
||||||
|
this.allocatedMemoryEnabled = jvm.isThreadAllocatedMemoryEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getThreadCount() {
|
public int getThreadCount() {
|
||||||
@ -91,6 +92,10 @@ class ThreadImpl implements ThreadMXBean {
|
|||||||
return jvm.isCurrentThreadCpuTimeSupported();
|
return jvm.isCurrentThreadCpuTimeSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isThreadAllocatedMemorySupported() {
|
||||||
|
return jvm.isThreadAllocatedMemorySupported();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isThreadCpuTimeEnabled() {
|
public boolean isThreadCpuTimeEnabled() {
|
||||||
if (!isThreadCpuTimeSupported() &&
|
if (!isThreadCpuTimeSupported() &&
|
||||||
!isCurrentThreadCpuTimeSupported()) {
|
!isCurrentThreadCpuTimeSupported()) {
|
||||||
@ -100,6 +105,14 @@ class ThreadImpl implements ThreadMXBean {
|
|||||||
return cpuTimeEnabled;
|
return cpuTimeEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isThreadAllocatedMemoryEnabled() {
|
||||||
|
if (!isThreadAllocatedMemorySupported()) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"Thread allocated memory measurement is not supported");
|
||||||
|
}
|
||||||
|
return allocatedMemoryEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
public long[] getAllThreadIds() {
|
public long[] getAllThreadIds() {
|
||||||
Util.checkMonitorAccess();
|
Util.checkMonitorAccess();
|
||||||
|
|
||||||
@ -114,11 +127,6 @@ class ThreadImpl implements ThreadMXBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ThreadInfo getThreadInfo(long id) {
|
public ThreadInfo getThreadInfo(long id) {
|
||||||
if (id <= 0) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Invalid thread ID parameter: " + id);
|
|
||||||
}
|
|
||||||
|
|
||||||
long[] ids = new long[1];
|
long[] ids = new long[1];
|
||||||
ids[0] = id;
|
ids[0] = id;
|
||||||
final ThreadInfo[] infos = getThreadInfo(ids, 0);
|
final ThreadInfo[] infos = getThreadInfo(ids, 0);
|
||||||
@ -126,15 +134,6 @@ class ThreadImpl implements ThreadMXBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ThreadInfo getThreadInfo(long id, int maxDepth) {
|
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];
|
long[] ids = new long[1];
|
||||||
ids[0] = id;
|
ids[0] = id;
|
||||||
final ThreadInfo[] infos = getThreadInfo(ids, maxDepth);
|
final ThreadInfo[] infos = getThreadInfo(ids, maxDepth);
|
||||||
@ -145,11 +144,22 @@ class ThreadImpl implements ThreadMXBean {
|
|||||||
return getThreadInfo(ids, 0);
|
return getThreadInfo(ids, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth) {
|
private void verifyThreadIds(long[] ids) {
|
||||||
if (ids == null) {
|
if (ids == null) {
|
||||||
throw new NullPointerException("Null ids parameter.");
|
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) {
|
if (maxDepth < 0) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Invalid maxDepth parameter: " + maxDepth);
|
"Invalid maxDepth parameter: " + maxDepth);
|
||||||
@ -157,17 +167,15 @@ class ThreadImpl implements ThreadMXBean {
|
|||||||
|
|
||||||
Util.checkMonitorAccess();
|
Util.checkMonitorAccess();
|
||||||
|
|
||||||
ThreadInfo[] infos = new ThreadInfo[ids.length];
|
ThreadInfo[] infos = new ThreadInfo[ids.length]; // nulls
|
||||||
if (maxDepth == Integer.MAX_VALUE) {
|
if (maxDepth == Integer.MAX_VALUE) {
|
||||||
getThreadInfo0(ids, -1, infos);
|
getThreadInfo1(ids, -1, infos);
|
||||||
} else {
|
} else {
|
||||||
getThreadInfo0(ids, maxDepth, infos);
|
getThreadInfo1(ids, maxDepth, infos);
|
||||||
}
|
}
|
||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void setThreadContentionMonitoringEnabled(boolean enable) {
|
public void setThreadContentionMonitoringEnabled(boolean enable) {
|
||||||
if (!isThreadContentionMonitoringSupported()) {
|
if (!isThreadContentionMonitoringSupported()) {
|
||||||
throw new UnsupportedOperationException(
|
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.
|
// check if Thread CPU time measurement is supported.
|
||||||
if (!isCurrentThreadCpuTimeSupported()) {
|
if (!isCurrentThreadCpuTimeSupported()) {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
"Current thread CPU time measurement is not supported.");
|
"Current thread CPU time measurement is not supported.");
|
||||||
}
|
}
|
||||||
|
return isThreadCpuTimeEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
if (!isThreadCpuTimeEnabled()) {
|
public long getCurrentThreadCpuTime() {
|
||||||
return -1;
|
if (verifyCurrentThreadCpuTime()) {
|
||||||
|
return getThreadTotalCpuTime0(0);
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
return getThreadTotalCpuTime0(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getThreadCpuTime(long id) {
|
public long getThreadCpuTime(long id) {
|
||||||
// check if Thread CPU time measurement is supported.
|
long[] ids = new long[1];
|
||||||
if (!isThreadCpuTimeSupported() &&
|
ids[0] = id;
|
||||||
!isCurrentThreadCpuTimeSupported()) {
|
final long[] times = getThreadCpuTime(ids);
|
||||||
throw new UnsupportedOperationException(
|
return times[0];
|
||||||
"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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getCurrentThreadUserTime() {
|
private boolean verifyThreadCpuTime(long[] ids) {
|
||||||
// check if Thread CPU time measurement is supported.
|
verifyThreadIds(ids);
|
||||||
if (!isCurrentThreadCpuTimeSupported()) {
|
|
||||||
throw new UnsupportedOperationException(
|
|
||||||
"Current thread CPU time measurement is not supported.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isThreadCpuTimeEnabled()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return getThreadUserCpuTime0(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getThreadUserTime(long id) {
|
|
||||||
// check if Thread CPU time measurement is supported.
|
// check if Thread CPU time measurement is supported.
|
||||||
if (!isThreadCpuTimeSupported() &&
|
if (!isThreadCpuTimeSupported() &&
|
||||||
!isCurrentThreadCpuTimeSupported()) {
|
!isCurrentThreadCpuTimeSupported()) {
|
||||||
@ -264,30 +235,71 @@ class ThreadImpl implements ThreadMXBean {
|
|||||||
|
|
||||||
if (!isThreadCpuTimeSupported()) {
|
if (!isThreadCpuTimeSupported()) {
|
||||||
// support current thread only
|
// support current thread only
|
||||||
if (id != Thread.currentThread().getId()) {
|
for (int i = 0; i < ids.length; i++) {
|
||||||
throw new UnsupportedOperationException(
|
if (ids[i] != Thread.currentThread().getId()) {
|
||||||
"Thread CPU time measurement is only supported" +
|
throw new UnsupportedOperationException(
|
||||||
" for the current thread.");
|
"Thread CPU time measurement is only supported" +
|
||||||
|
" for the current thread.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id <= 0) {
|
return isThreadCpuTimeEnabled();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
public void setThreadCpuTimeEnabled(boolean enable) {
|
||||||
if (!isThreadCpuTimeSupported() &&
|
if (!isThreadCpuTimeSupported() &&
|
||||||
@ -299,13 +311,59 @@ class ThreadImpl implements ThreadMXBean {
|
|||||||
Util.checkControlAccess();
|
Util.checkControlAccess();
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (cpuTimeEnabled != enable) {
|
if (cpuTimeEnabled != enable) {
|
||||||
// update VM of the state change
|
// notify VM of the state change
|
||||||
setThreadCpuTimeEnabled0(enable);
|
setThreadCpuTimeEnabled0(enable);
|
||||||
cpuTimeEnabled = 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() {
|
public long[] findMonitorDeadlockedThreads() {
|
||||||
Util.checkMonitorAccess();
|
Util.checkMonitorAccess();
|
||||||
|
|
||||||
@ -356,49 +414,47 @@ class ThreadImpl implements ThreadMXBean {
|
|||||||
return jvm.isSynchronizerUsageSupported();
|
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,
|
public ThreadInfo[] getThreadInfo(long[] ids,
|
||||||
boolean lockedMonitors,
|
boolean lockedMonitors,
|
||||||
boolean lockedSynchronizers) {
|
boolean lockedSynchronizers) {
|
||||||
if (ids == null) {
|
verifyThreadIds(ids);
|
||||||
throw new NullPointerException("Null ids parameter.");
|
verifyDumpThreads(lockedMonitors, 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);
|
return dumpThreads0(ids, lockedMonitors, lockedSynchronizers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ThreadInfo[] dumpAllThreads(boolean lockedMonitors,
|
||||||
public ThreadInfo[] dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers) {
|
boolean lockedSynchronizers) {
|
||||||
if (lockedMonitors && !isObjectMonitorUsageSupported()) {
|
verifyDumpThreads(lockedMonitors, lockedSynchronizers);
|
||||||
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(null, lockedMonitors, lockedSynchronizers);
|
return dumpThreads0(null, lockedMonitors, lockedSynchronizers);
|
||||||
}
|
}
|
||||||
|
|
||||||
// VM support where maxDepth == -1 to request entire stack dump
|
// VM support where maxDepth == -1 to request entire stack dump
|
||||||
private static native Thread[] getThreads();
|
private static native Thread[] getThreads();
|
||||||
private static native void getThreadInfo0(long[] ids,
|
private static native void getThreadInfo1(long[] ids,
|
||||||
int maxDepth,
|
int maxDepth,
|
||||||
ThreadInfo[] result);
|
ThreadInfo[] result);
|
||||||
private static native long getThreadTotalCpuTime0(long id);
|
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 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 setThreadCpuTimeEnabled0(boolean enable);
|
||||||
|
private static native void setThreadAllocatedMemoryEnabled0(boolean enable);
|
||||||
private static native void setThreadContentionMonitoringEnabled0(boolean enable);
|
private static native void setThreadContentionMonitoringEnabled0(boolean enable);
|
||||||
private static native Thread[] findMonitorDeadlockedThreads0();
|
private static native Thread[] findMonitorDeadlockedThreads0();
|
||||||
private static native Thread[] findDeadlockedThreads0();
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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 isBootClassPathSupported();
|
||||||
public boolean isObjectMonitorUsageSupported();
|
public boolean isObjectMonitorUsageSupported();
|
||||||
public boolean isSynchronizerUsageSupported();
|
public boolean isSynchronizerUsageSupported();
|
||||||
|
public boolean isThreadAllocatedMemorySupported();
|
||||||
|
public boolean isThreadAllocatedMemoryEnabled();
|
||||||
|
|
||||||
// Class Loading Subsystem
|
// Class Loading Subsystem
|
||||||
public long getTotalClassCount();
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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 bootClassPathSupport;
|
||||||
private static boolean objectMonitorUsageSupport;
|
private static boolean objectMonitorUsageSupport;
|
||||||
private static boolean synchronizerUsageSupport;
|
private static boolean synchronizerUsageSupport;
|
||||||
|
private static boolean threadAllocatedMemorySupport;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
version = getVersion0();
|
version = getVersion0();
|
||||||
@ -95,9 +96,13 @@ class VMManagementImpl implements VMManagement {
|
|||||||
return synchronizerUsageSupport;
|
return synchronizerUsageSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isThreadAllocatedMemorySupported() {
|
||||||
|
return threadAllocatedMemorySupport;
|
||||||
|
}
|
||||||
|
|
||||||
public native boolean isThreadContentionMonitoringEnabled();
|
public native boolean isThreadContentionMonitoringEnabled();
|
||||||
public native boolean isThreadCpuTimeEnabled();
|
public native boolean isThreadCpuTimeEnabled();
|
||||||
|
public native boolean isThreadAllocatedMemoryEnabled();
|
||||||
|
|
||||||
// Class Loading Subsystem
|
// Class Loading Subsystem
|
||||||
public int getLoadedClassCount() {
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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 isBootClassPathSupported : 1;
|
||||||
unsigned int isObjectMonitorUsageSupported : 1;
|
unsigned int isObjectMonitorUsageSupported : 1;
|
||||||
unsigned int isSynchronizerUsageSupported : 1;
|
unsigned int isSynchronizerUsageSupported : 1;
|
||||||
unsigned int : 24;
|
unsigned int isThreadAllocatedMemorySupported : 1;
|
||||||
|
unsigned int : 23;
|
||||||
} jmmOptionalSupport;
|
} jmmOptionalSupport;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -105,7 +106,8 @@ typedef enum {
|
|||||||
JMM_VERBOSE_GC = 21,
|
JMM_VERBOSE_GC = 21,
|
||||||
JMM_VERBOSE_CLASS = 22,
|
JMM_VERBOSE_CLASS = 22,
|
||||||
JMM_THREAD_CONTENTION_MONITORING = 23,
|
JMM_THREAD_CONTENTION_MONITORING = 23,
|
||||||
JMM_THREAD_CPU_TIME = 24
|
JMM_THREAD_CPU_TIME = 24,
|
||||||
|
JMM_THREAD_ALLOCATED_MEMORY = 25
|
||||||
} jmmBoolAttribute;
|
} jmmBoolAttribute;
|
||||||
|
|
||||||
|
|
||||||
@ -213,7 +215,10 @@ typedef struct jmmInterface_1_ {
|
|||||||
jobject (JNICALL *GetMemoryPoolUsage) (JNIEnv* env, jobject pool);
|
jobject (JNICALL *GetMemoryPoolUsage) (JNIEnv* env, jobject pool);
|
||||||
jobject (JNICALL *GetPeakMemoryPoolUsage) (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);
|
jobject (JNICALL *GetMemoryUsage) (JNIEnv* env, jboolean heap);
|
||||||
|
|
||||||
@ -228,6 +233,8 @@ typedef struct jmmInterface_1_ {
|
|||||||
jlong* result);
|
jlong* result);
|
||||||
|
|
||||||
jobjectArray (JNICALL *FindCircularBlockedThreads) (JNIEnv *env);
|
jobjectArray (JNICALL *FindCircularBlockedThreads) (JNIEnv *env);
|
||||||
|
|
||||||
|
// Not used in JDK 6 or JDK 7
|
||||||
jlong (JNICALL *GetThreadCpuTime) (JNIEnv *env, jlong thread_id);
|
jlong (JNICALL *GetThreadCpuTime) (JNIEnv *env, jlong thread_id);
|
||||||
|
|
||||||
jobjectArray (JNICALL *GetVMGlobalNames) (JNIEnv *env);
|
jobjectArray (JNICALL *GetVMGlobalNames) (JNIEnv *env);
|
||||||
@ -262,14 +269,22 @@ typedef struct jmmInterface_1_ {
|
|||||||
void (JNICALL *GetLastGCStat) (JNIEnv *env,
|
void (JNICALL *GetLastGCStat) (JNIEnv *env,
|
||||||
jobject mgr,
|
jobject mgr,
|
||||||
jmmGCStat *gc_stat);
|
jmmGCStat *gc_stat);
|
||||||
jlong (JNICALL *GetThreadCpuTimeWithKind) (JNIEnv *env,
|
|
||||||
jlong thread_id,
|
jlong (JNICALL *GetThreadCpuTimeWithKind)
|
||||||
jboolean user_sys_cpu_time);
|
(JNIEnv *env,
|
||||||
void* reserved5;
|
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,
|
jint (JNICALL *DumpHeap0) (JNIEnv *env,
|
||||||
jstring outputfile,
|
jstring outputfile,
|
||||||
jboolean live);
|
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,
|
void (JNICALL *SetVMGlobal) (JNIEnv *env,
|
||||||
jstring flag_name,
|
jstring flag_name,
|
||||||
jvalue new_value);
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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);
|
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
|
JNIEXPORT void JNICALL
|
||||||
Java_sun_management_ThreadImpl_getThreadInfo0
|
Java_sun_management_ThreadImpl_getThreadInfo1
|
||||||
(JNIEnv *env, jclass cls, jlongArray ids, jint maxDepth,
|
(JNIEnv *env, jclass cls, jlongArray ids, jint maxDepth,
|
||||||
jobjectArray infoArray)
|
jobjectArray infoArray)
|
||||||
{
|
{
|
||||||
@ -65,6 +71,14 @@ Java_sun_management_ThreadImpl_getThreadTotalCpuTime0
|
|||||||
return jmm_interface->GetThreadCpuTimeWithKind(env, tid, JNI_TRUE /* user+sys */);
|
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
|
JNIEXPORT jlong JNICALL
|
||||||
Java_sun_management_ThreadImpl_getThreadUserCpuTime0
|
Java_sun_management_ThreadImpl_getThreadUserCpuTime0
|
||||||
(JNIEnv *env, jclass cls, jlong tid)
|
(JNIEnv *env, jclass cls, jlong tid)
|
||||||
@ -72,6 +86,21 @@ Java_sun_management_ThreadImpl_getThreadUserCpuTime0
|
|||||||
return jmm_interface->GetThreadCpuTimeWithKind(env, tid, JNI_FALSE /* user */);
|
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
|
JNIEXPORT jobjectArray JNICALL
|
||||||
Java_sun_management_ThreadImpl_findMonitorDeadlockedThreads0
|
Java_sun_management_ThreadImpl_findMonitorDeadlockedThreads0
|
||||||
(JNIEnv *env, jclass cls)
|
(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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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, "objectMonitorUsageSupport", JNI_FALSE);
|
||||||
setStaticBooleanField(env, cls, "synchronizerUsageSupport", JNI_FALSE);
|
setStaticBooleanField(env, cls, "synchronizerUsageSupport", JNI_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value = mos.isThreadAllocatedMemorySupported;
|
||||||
|
setStaticBooleanField(env, cls, "threadAllocatedMemorySupport", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jobjectArray JNICALL
|
JNIEXPORT jobjectArray JNICALL
|
||||||
@ -201,6 +204,13 @@ Java_sun_management_VMManagementImpl_isThreadCpuTimeEnabled
|
|||||||
return jmm_interface->GetBoolAttribute(env, JMM_THREAD_CPU_TIME);
|
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
|
JNIEXPORT jint JNICALL
|
||||||
Java_sun_management_VMManagementImpl_getProcessId
|
Java_sun_management_VMManagementImpl_getProcessId
|
||||||
(JNIEnv *env, jobject dummy)
|
(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