Path: blob/master/src/java.management/share/classes/sun/management/ThreadImpl.java
41152 views
/*1* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.management;2627import java.lang.management.ManagementFactory;28import java.lang.management.ThreadInfo;29import java.lang.management.ThreadMXBean;30import javax.management.ObjectName;31import java.util.Objects;3233/**34* Implementation for java.lang.management.ThreadMXBean as well as providing the35* supporting method for com.sun.management.ThreadMXBean.36* The supporting method for com.sun.management.ThreadMXBean can be moved to37* jdk.management in the future.38*/3940public class ThreadImpl implements ThreadMXBean {41private final VMManagement jvm;4243// default for thread contention monitoring is disabled.44private boolean contentionMonitoringEnabled = false;45private boolean cpuTimeEnabled;46private boolean allocatedMemoryEnabled;4748/**49* Constructor of ThreadImpl class.50*/51protected ThreadImpl(VMManagement vm) {52this.jvm = vm;53this.cpuTimeEnabled = jvm.isThreadCpuTimeEnabled();54this.allocatedMemoryEnabled = jvm.isThreadAllocatedMemoryEnabled();55}5657@Override58public int getThreadCount() {59return jvm.getLiveThreadCount();60}6162@Override63public int getPeakThreadCount() {64return jvm.getPeakThreadCount();65}6667@Override68public long getTotalStartedThreadCount() {69return jvm.getTotalThreadCount();70}7172@Override73public int getDaemonThreadCount() {74return jvm.getDaemonThreadCount();75}7677@Override78public boolean isThreadContentionMonitoringSupported() {79return jvm.isThreadContentionMonitoringSupported();80}8182@Override83public synchronized boolean isThreadContentionMonitoringEnabled() {84if (!isThreadContentionMonitoringSupported()) {85throw new UnsupportedOperationException(86"Thread contention monitoring is not supported.");87}88return contentionMonitoringEnabled;89}9091@Override92public boolean isThreadCpuTimeSupported() {93return jvm.isOtherThreadCpuTimeSupported();94}9596@Override97public boolean isCurrentThreadCpuTimeSupported() {98return jvm.isCurrentThreadCpuTimeSupported();99}100101protected boolean isThreadAllocatedMemorySupported() {102return jvm.isThreadAllocatedMemorySupported();103}104105@Override106public boolean isThreadCpuTimeEnabled() {107if (!isThreadCpuTimeSupported() &&108!isCurrentThreadCpuTimeSupported()) {109throw new UnsupportedOperationException(110"Thread CPU time measurement is not supported");111}112return cpuTimeEnabled;113}114115private void ensureThreadAllocatedMemorySupported() {116if (!isThreadAllocatedMemorySupported()) {117throw new UnsupportedOperationException(118"Thread allocated memory measurement is not supported.");119}120}121122protected boolean isThreadAllocatedMemoryEnabled() {123ensureThreadAllocatedMemorySupported();124return allocatedMemoryEnabled;125}126127@Override128public long[] getAllThreadIds() {129Util.checkMonitorAccess();130131Thread[] threads = getThreads();132int length = threads.length;133long[] ids = new long[length];134for (int i = 0; i < length; i++) {135Thread t = threads[i];136ids[i] = t.getId();137}138return ids;139}140141@Override142public ThreadInfo getThreadInfo(long id) {143long[] ids = new long[1];144ids[0] = id;145final ThreadInfo[] infos = getThreadInfo(ids, 0);146return infos[0];147}148149@Override150public ThreadInfo getThreadInfo(long id, int maxDepth) {151long[] ids = new long[1];152ids[0] = id;153final ThreadInfo[] infos = getThreadInfo(ids, maxDepth);154return infos[0];155}156157@Override158public ThreadInfo[] getThreadInfo(long[] ids) {159return getThreadInfo(ids, 0);160}161162private void verifyThreadId(long id) {163if (id <= 0) {164throw new IllegalArgumentException(165"Invalid thread ID parameter: " + id);166}167}168169private void verifyThreadIds(long[] ids) {170Objects.requireNonNull(ids);171172for (int i = 0; i < ids.length; i++) {173verifyThreadId(ids[i]);174}175}176177@Override178public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth) {179verifyThreadIds(ids);180181if (maxDepth < 0) {182throw new IllegalArgumentException(183"Invalid maxDepth parameter: " + maxDepth);184}185186// ids has been verified to be non-null187// an empty array of ids should return an empty array of ThreadInfos188if (ids.length == 0) return new ThreadInfo[0];189190Util.checkMonitorAccess();191192ThreadInfo[] infos = new ThreadInfo[ids.length]; // nulls193if (maxDepth == Integer.MAX_VALUE) {194getThreadInfo1(ids, -1, infos);195} else {196getThreadInfo1(ids, maxDepth, infos);197}198return infos;199}200201@Override202public void setThreadContentionMonitoringEnabled(boolean enable) {203if (!isThreadContentionMonitoringSupported()) {204throw new UnsupportedOperationException(205"Thread contention monitoring is not supported");206}207208Util.checkControlAccess();209210synchronized (this) {211if (contentionMonitoringEnabled != enable) {212if (enable) {213// if reeabled, reset contention time statistics214// for all threads215resetContentionTimes0(0);216}217218// update the VM of the state change219setThreadContentionMonitoringEnabled0(enable);220221contentionMonitoringEnabled = enable;222}223}224}225226private boolean verifyCurrentThreadCpuTime() {227// check if Thread CPU time measurement is supported.228if (!isCurrentThreadCpuTimeSupported()) {229throw new UnsupportedOperationException(230"Current thread CPU time measurement is not supported.");231}232return isThreadCpuTimeEnabled();233}234235@Override236public long getCurrentThreadCpuTime() {237if (verifyCurrentThreadCpuTime()) {238return getThreadTotalCpuTime0(0);239}240return -1;241}242243@Override244public long getThreadCpuTime(long id) {245long[] ids = new long[1];246ids[0] = id;247final long[] times = getThreadCpuTime(ids);248return times[0];249}250251private boolean verifyThreadCpuTime(long[] ids) {252verifyThreadIds(ids);253254// check if Thread CPU time measurement is supported.255if (!isThreadCpuTimeSupported() &&256!isCurrentThreadCpuTimeSupported()) {257throw new UnsupportedOperationException(258"Thread CPU time measurement is not supported.");259}260261if (!isThreadCpuTimeSupported()) {262// support current thread only263for (int i = 0; i < ids.length; i++) {264if (ids[i] != Thread.currentThread().getId()) {265throw new UnsupportedOperationException(266"Thread CPU time measurement is only supported" +267" for the current thread.");268}269}270}271272return isThreadCpuTimeEnabled();273}274275protected long[] getThreadCpuTime(long[] ids) {276boolean verified = verifyThreadCpuTime(ids);277278int length = ids.length;279long[] times = new long[length];280java.util.Arrays.fill(times, -1);281282if (verified) {283if (length == 1) {284long id = ids[0];285if (id == Thread.currentThread().getId()) {286id = 0;287}288times[0] = getThreadTotalCpuTime0(id);289} else {290getThreadTotalCpuTime1(ids, times);291}292}293return times;294}295296@Override297public long getCurrentThreadUserTime() {298if (verifyCurrentThreadCpuTime()) {299return getThreadUserCpuTime0(0);300}301return -1;302}303304@Override305public long getThreadUserTime(long id) {306long[] ids = new long[1];307ids[0] = id;308final long[] times = getThreadUserTime(ids);309return times[0];310}311312protected long[] getThreadUserTime(long[] ids) {313boolean verified = verifyThreadCpuTime(ids);314315int length = ids.length;316long[] times = new long[length];317java.util.Arrays.fill(times, -1);318319if (verified) {320if (length == 1) {321long id = ids[0];322if (id == Thread.currentThread().getId()) {323id = 0;324}325times[0] = getThreadUserCpuTime0(id);326} else {327getThreadUserCpuTime1(ids, times);328}329}330return times;331}332333@Override334public void setThreadCpuTimeEnabled(boolean enable) {335if (!isThreadCpuTimeSupported() &&336!isCurrentThreadCpuTimeSupported()) {337throw new UnsupportedOperationException(338"Thread CPU time measurement is not supported");339}340341Util.checkControlAccess();342synchronized (this) {343if (cpuTimeEnabled != enable) {344// notify VM of the state change345setThreadCpuTimeEnabled0(enable);346cpuTimeEnabled = enable;347}348}349}350351protected long getCurrentThreadAllocatedBytes() {352if (isThreadAllocatedMemoryEnabled()) {353return getThreadAllocatedMemory0(0);354}355return -1;356}357358private boolean verifyThreadAllocatedMemory(long id) {359verifyThreadId(id);360return isThreadAllocatedMemoryEnabled();361}362363protected long getThreadAllocatedBytes(long id) {364boolean verified = verifyThreadAllocatedMemory(id);365366if (verified) {367return getThreadAllocatedMemory0(368Thread.currentThread().getId() == id ? 0 : id);369}370return -1;371}372373private boolean verifyThreadAllocatedMemory(long[] ids) {374verifyThreadIds(ids);375return isThreadAllocatedMemoryEnabled();376}377378protected long[] getThreadAllocatedBytes(long[] ids) {379Objects.requireNonNull(ids);380381if (ids.length == 1) {382long size = getThreadAllocatedBytes(ids[0]);383return new long[] { size };384}385386boolean verified = verifyThreadAllocatedMemory(ids);387388long[] sizes = new long[ids.length];389java.util.Arrays.fill(sizes, -1);390391if (verified) {392getThreadAllocatedMemory1(ids, sizes);393}394return sizes;395}396397protected void setThreadAllocatedMemoryEnabled(boolean enable) {398ensureThreadAllocatedMemorySupported();399400Util.checkControlAccess();401synchronized (this) {402if (allocatedMemoryEnabled != enable) {403// notify VM of the state change404setThreadAllocatedMemoryEnabled0(enable);405allocatedMemoryEnabled = enable;406}407}408}409410@Override411public long[] findMonitorDeadlockedThreads() {412Util.checkMonitorAccess();413414Thread[] threads = findMonitorDeadlockedThreads0();415if (threads == null) {416return null;417}418419long[] ids = new long[threads.length];420for (int i = 0; i < threads.length; i++) {421Thread t = threads[i];422ids[i] = t.getId();423}424return ids;425}426427@Override428public long[] findDeadlockedThreads() {429if (!isSynchronizerUsageSupported()) {430throw new UnsupportedOperationException(431"Monitoring of Synchronizer Usage is not supported.");432}433434Util.checkMonitorAccess();435436Thread[] threads = findDeadlockedThreads0();437if (threads == null) {438return null;439}440441long[] ids = new long[threads.length];442for (int i = 0; i < threads.length; i++) {443Thread t = threads[i];444ids[i] = t.getId();445}446return ids;447}448449@Override450public void resetPeakThreadCount() {451Util.checkControlAccess();452resetPeakThreadCount0();453}454455@Override456public boolean isObjectMonitorUsageSupported() {457return jvm.isObjectMonitorUsageSupported();458}459460@Override461public boolean isSynchronizerUsageSupported() {462return jvm.isSynchronizerUsageSupported();463}464465private void verifyDumpThreads(boolean lockedMonitors,466boolean lockedSynchronizers) {467if (lockedMonitors && !isObjectMonitorUsageSupported()) {468throw new UnsupportedOperationException(469"Monitoring of Object Monitor Usage is not supported.");470}471472if (lockedSynchronizers && !isSynchronizerUsageSupported()) {473throw new UnsupportedOperationException(474"Monitoring of Synchronizer Usage is not supported.");475}476477Util.checkMonitorAccess();478}479480@Override481public ThreadInfo[] getThreadInfo(long[] ids,482boolean lockedMonitors,483boolean lockedSynchronizers) {484return dumpThreads0(ids, lockedMonitors, lockedSynchronizers,485Integer.MAX_VALUE);486}487488public ThreadInfo[] getThreadInfo(long[] ids,489boolean lockedMonitors,490boolean lockedSynchronizers,491int maxDepth) {492if (maxDepth < 0) {493throw new IllegalArgumentException(494"Invalid maxDepth parameter: " + maxDepth);495}496verifyThreadIds(ids);497// ids has been verified to be non-null498// an empty array of ids should return an empty array of ThreadInfos499if (ids.length == 0) return new ThreadInfo[0];500501verifyDumpThreads(lockedMonitors, lockedSynchronizers);502return dumpThreads0(ids, lockedMonitors, lockedSynchronizers, maxDepth);503}504505@Override506public ThreadInfo[] dumpAllThreads(boolean lockedMonitors,507boolean lockedSynchronizers) {508return dumpAllThreads(lockedMonitors, lockedSynchronizers,509Integer.MAX_VALUE);510}511512public ThreadInfo[] dumpAllThreads(boolean lockedMonitors,513boolean lockedSynchronizers,514int maxDepth) {515if (maxDepth < 0) {516throw new IllegalArgumentException(517"Invalid maxDepth parameter: " + maxDepth);518}519verifyDumpThreads(lockedMonitors, lockedSynchronizers);520return dumpThreads0(null, lockedMonitors, lockedSynchronizers, maxDepth);521}522523// VM support where maxDepth == -1 to request entire stack dump524private static native Thread[] getThreads();525private static native void getThreadInfo1(long[] ids,526int maxDepth,527ThreadInfo[] result);528private static native long getThreadTotalCpuTime0(long id);529private static native void getThreadTotalCpuTime1(long[] ids, long[] result);530private static native long getThreadUserCpuTime0(long id);531private static native void getThreadUserCpuTime1(long[] ids, long[] result);532private static native long getThreadAllocatedMemory0(long id);533private static native void getThreadAllocatedMemory1(long[] ids, long[] result);534private static native void setThreadCpuTimeEnabled0(boolean enable);535private static native void setThreadAllocatedMemoryEnabled0(boolean enable);536private static native void setThreadContentionMonitoringEnabled0(boolean enable);537private static native Thread[] findMonitorDeadlockedThreads0();538private static native Thread[] findDeadlockedThreads0();539private static native void resetPeakThreadCount0();540private static native ThreadInfo[] dumpThreads0(long[] ids,541boolean lockedMonitors,542boolean lockedSynchronizers,543int maxDepth);544545// tid == 0 to reset contention times for all threads546private static native void resetContentionTimes0(long tid);547548@Override549public ObjectName getObjectName() {550return Util.newObjectName(ManagementFactory.THREAD_MXBEAN_NAME);551}552553}554555556