Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/management/ThreadImpl.java
38827 views
/*1* Copyright (c) 2003, 2019, 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;2829import java.lang.management.ThreadInfo;3031import javax.management.ObjectName;32import java.util.Objects;3334/**35* Implementation class for the thread subsystem.36* Standard and committed hotspot-specific metrics if any.37*38* ManagementFactory.getThreadMXBean() returns an instance39* of this class.40*/41class ThreadImpl implements com.sun.management.ThreadMXBean {4243private final VMManagement jvm;4445// default for thread contention monitoring is disabled.46private boolean contentionMonitoringEnabled = false;47private boolean cpuTimeEnabled;48private boolean allocatedMemoryEnabled;4950/**51* Constructor of ThreadImpl class.52*/53ThreadImpl(VMManagement vm) {54this.jvm = vm;55this.cpuTimeEnabled = jvm.isThreadCpuTimeEnabled();56this.allocatedMemoryEnabled = jvm.isThreadAllocatedMemoryEnabled();57}5859public int getThreadCount() {60return jvm.getLiveThreadCount();61}6263public int getPeakThreadCount() {64return jvm.getPeakThreadCount();65}6667public long getTotalStartedThreadCount() {68return jvm.getTotalThreadCount();69}7071public int getDaemonThreadCount() {72return jvm.getDaemonThreadCount();73}7475public boolean isThreadContentionMonitoringSupported() {76return jvm.isThreadContentionMonitoringSupported();77}7879public synchronized boolean isThreadContentionMonitoringEnabled() {80if (!isThreadContentionMonitoringSupported()) {81throw new UnsupportedOperationException(82"Thread contention monitoring is not supported.");83}84return contentionMonitoringEnabled;85}8687public boolean isThreadCpuTimeSupported() {88return jvm.isOtherThreadCpuTimeSupported();89}9091public boolean isCurrentThreadCpuTimeSupported() {92return jvm.isCurrentThreadCpuTimeSupported();93}9495public boolean isThreadAllocatedMemorySupported() {96return jvm.isThreadAllocatedMemorySupported();97}9899public boolean isThreadCpuTimeEnabled() {100if (!isThreadCpuTimeSupported() &&101!isCurrentThreadCpuTimeSupported()) {102throw new UnsupportedOperationException(103"Thread CPU time measurement is not supported");104}105return cpuTimeEnabled;106}107108private void ensureThreadAllocatedMemorySupported() {109if (!isThreadAllocatedMemorySupported()) {110throw new UnsupportedOperationException(111"Thread allocated memory measurement is not supported.");112}113}114115public boolean isThreadAllocatedMemoryEnabled() {116ensureThreadAllocatedMemorySupported();117return allocatedMemoryEnabled;118}119120public long[] getAllThreadIds() {121Util.checkMonitorAccess();122123Thread[] threads = getThreads();124int length = threads.length;125long[] ids = new long[length];126for (int i = 0; i < length; i++) {127Thread t = threads[i];128ids[i] = t.getId();129}130return ids;131}132133public ThreadInfo getThreadInfo(long id) {134long[] ids = new long[1];135ids[0] = id;136final ThreadInfo[] infos = getThreadInfo(ids, 0);137return infos[0];138}139140public ThreadInfo getThreadInfo(long id, int maxDepth) {141long[] ids = new long[1];142ids[0] = id;143final ThreadInfo[] infos = getThreadInfo(ids, maxDepth);144return infos[0];145}146147public ThreadInfo[] getThreadInfo(long[] ids) {148return getThreadInfo(ids, 0);149}150151private void verifyThreadId(long id) {152if (id <= 0) {153throw new IllegalArgumentException(154"Invalid thread ID parameter: " + id);155}156}157158private void verifyThreadIds(long[] ids) {159Objects.requireNonNull(ids);160161for (int i = 0; i < ids.length; i++) {162verifyThreadId(ids[i]);163}164}165166public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth) {167verifyThreadIds(ids);168169if (maxDepth < 0) {170throw new IllegalArgumentException(171"Invalid maxDepth parameter: " + maxDepth);172}173174// ids has been verified to be non-null175// an empty array of ids should return an empty array of ThreadInfos176if (ids.length == 0) return new ThreadInfo[0];177178Util.checkMonitorAccess();179180ThreadInfo[] infos = new ThreadInfo[ids.length]; // nulls181if (maxDepth == Integer.MAX_VALUE) {182getThreadInfo1(ids, -1, infos);183} else {184getThreadInfo1(ids, maxDepth, infos);185}186return infos;187}188189public void setThreadContentionMonitoringEnabled(boolean enable) {190if (!isThreadContentionMonitoringSupported()) {191throw new UnsupportedOperationException(192"Thread contention monitoring is not supported");193}194195Util.checkControlAccess();196197synchronized (this) {198if (contentionMonitoringEnabled != enable) {199if (enable) {200// if reeabled, reset contention time statistics201// for all threads202resetContentionTimes0(0);203}204205// update the VM of the state change206setThreadContentionMonitoringEnabled0(enable);207208contentionMonitoringEnabled = enable;209}210}211}212213private boolean verifyCurrentThreadCpuTime() {214// check if Thread CPU time measurement is supported.215if (!isCurrentThreadCpuTimeSupported()) {216throw new UnsupportedOperationException(217"Current thread CPU time measurement is not supported.");218}219return isThreadCpuTimeEnabled();220}221222public long getCurrentThreadCpuTime() {223if (verifyCurrentThreadCpuTime()) {224return getThreadTotalCpuTime0(0);225}226return -1;227}228229public long getThreadCpuTime(long id) {230long[] ids = new long[1];231ids[0] = id;232final long[] times = getThreadCpuTime(ids);233return times[0];234}235236private boolean verifyThreadCpuTime(long[] ids) {237verifyThreadIds(ids);238239// check if Thread CPU time measurement is supported.240if (!isThreadCpuTimeSupported() &&241!isCurrentThreadCpuTimeSupported()) {242throw new UnsupportedOperationException(243"Thread CPU time measurement is not supported.");244}245246if (!isThreadCpuTimeSupported()) {247// support current thread only248for (int i = 0; i < ids.length; i++) {249if (ids[i] != Thread.currentThread().getId()) {250throw new UnsupportedOperationException(251"Thread CPU time measurement is only supported" +252" for the current thread.");253}254}255}256257return isThreadCpuTimeEnabled();258}259260public long[] getThreadCpuTime(long[] ids) {261boolean verified = verifyThreadCpuTime(ids);262263int length = ids.length;264long[] times = new long[length];265java.util.Arrays.fill(times, -1);266267if (verified) {268if (length == 1) {269long id = ids[0];270if (id == Thread.currentThread().getId()) {271id = 0;272}273times[0] = getThreadTotalCpuTime0(id);274} else {275getThreadTotalCpuTime1(ids, times);276}277}278return times;279}280281public long getCurrentThreadUserTime() {282if (verifyCurrentThreadCpuTime()) {283return getThreadUserCpuTime0(0);284}285return -1;286}287288public long getThreadUserTime(long id) {289long[] ids = new long[1];290ids[0] = id;291final long[] times = getThreadUserTime(ids);292return times[0];293}294295public long[] getThreadUserTime(long[] ids) {296boolean verified = verifyThreadCpuTime(ids);297298int length = ids.length;299long[] times = new long[length];300java.util.Arrays.fill(times, -1);301302if (verified) {303if (length == 1) {304long id = ids[0];305if (id == Thread.currentThread().getId()) {306id = 0;307}308times[0] = getThreadUserCpuTime0(id);309} else {310getThreadUserCpuTime1(ids, times);311}312}313return times;314}315316public void setThreadCpuTimeEnabled(boolean enable) {317if (!isThreadCpuTimeSupported() &&318!isCurrentThreadCpuTimeSupported()) {319throw new UnsupportedOperationException(320"Thread CPU time measurement is not supported");321}322323Util.checkControlAccess();324synchronized (this) {325if (cpuTimeEnabled != enable) {326// notify VM of the state change327setThreadCpuTimeEnabled0(enable);328cpuTimeEnabled = enable;329}330}331}332333public long getCurrentThreadAllocatedBytes() {334if (isThreadAllocatedMemoryEnabled()) {335return getThreadAllocatedMemory0(0);336}337return -1;338}339340private boolean verifyThreadAllocatedMemory(long id) {341verifyThreadId(id);342return isThreadAllocatedMemoryEnabled();343}344345public long getThreadAllocatedBytes(long id) {346boolean verified = verifyThreadAllocatedMemory(id);347348if (verified) {349return getThreadAllocatedMemory0(350Thread.currentThread().getId() == id ? 0 : id);351}352return -1;353}354355private boolean verifyThreadAllocatedMemory(long[] ids) {356verifyThreadIds(ids);357return isThreadAllocatedMemoryEnabled();358}359360public long[] getThreadAllocatedBytes(long[] ids) {361Objects.requireNonNull(ids);362363if (ids.length == 1) {364long size = getThreadAllocatedBytes(ids[0]);365return new long[] { size };366}367368boolean verified = verifyThreadAllocatedMemory(ids);369370long[] sizes = new long[ids.length];371java.util.Arrays.fill(sizes, -1);372373if (verified) {374getThreadAllocatedMemory1(ids, sizes);375}376return sizes;377}378379public void setThreadAllocatedMemoryEnabled(boolean enable) {380ensureThreadAllocatedMemorySupported();381382Util.checkControlAccess();383synchronized (this) {384if (allocatedMemoryEnabled != enable) {385// notify VM of the state change386setThreadAllocatedMemoryEnabled0(enable);387allocatedMemoryEnabled = enable;388}389}390}391392public long[] findMonitorDeadlockedThreads() {393Util.checkMonitorAccess();394395Thread[] threads = findMonitorDeadlockedThreads0();396if (threads == null) {397return null;398}399400long[] ids = new long[threads.length];401for (int i = 0; i < threads.length; i++) {402Thread t = threads[i];403ids[i] = t.getId();404}405return ids;406}407408public long[] findDeadlockedThreads() {409if (!isSynchronizerUsageSupported()) {410throw new UnsupportedOperationException(411"Monitoring of Synchronizer Usage is not supported.");412}413414Util.checkMonitorAccess();415416Thread[] threads = findDeadlockedThreads0();417if (threads == null) {418return null;419}420421long[] ids = new long[threads.length];422for (int i = 0; i < threads.length; i++) {423Thread t = threads[i];424ids[i] = t.getId();425}426return ids;427}428429public void resetPeakThreadCount() {430Util.checkControlAccess();431resetPeakThreadCount0();432}433434public boolean isObjectMonitorUsageSupported() {435return jvm.isObjectMonitorUsageSupported();436}437438public boolean isSynchronizerUsageSupported() {439return jvm.isSynchronizerUsageSupported();440}441442private void verifyDumpThreads(boolean lockedMonitors,443boolean lockedSynchronizers) {444if (lockedMonitors && !isObjectMonitorUsageSupported()) {445throw new UnsupportedOperationException(446"Monitoring of Object Monitor Usage is not supported.");447}448449if (lockedSynchronizers && !isSynchronizerUsageSupported()) {450throw new UnsupportedOperationException(451"Monitoring of Synchronizer Usage is not supported.");452}453454Util.checkMonitorAccess();455}456457public ThreadInfo[] getThreadInfo(long[] ids,458boolean lockedMonitors,459boolean lockedSynchronizers) {460return dumpThreads0(ids, lockedMonitors, lockedSynchronizers,461Integer.MAX_VALUE);462}463464public ThreadInfo[] getThreadInfo(long[] ids,465boolean lockedMonitors,466boolean lockedSynchronizers,467int maxDepth) {468if (maxDepth < 0) {469throw new IllegalArgumentException(470"Invalid maxDepth parameter: " + maxDepth);471}472verifyThreadIds(ids);473// ids has been verified to be non-null474// an empty array of ids should return an empty array of ThreadInfos475if (ids.length == 0) return new ThreadInfo[0];476477verifyDumpThreads(lockedMonitors, lockedSynchronizers);478return dumpThreads0(ids, lockedMonitors, lockedSynchronizers, maxDepth);479}480481public ThreadInfo[] dumpAllThreads(boolean lockedMonitors,482boolean lockedSynchronizers) {483return dumpAllThreads(lockedMonitors, lockedSynchronizers,484Integer.MAX_VALUE);485}486487public ThreadInfo[] dumpAllThreads(boolean lockedMonitors,488boolean lockedSynchronizers,489int maxDepth) {490if (maxDepth < 0) {491throw new IllegalArgumentException(492"Invalid maxDepth parameter: " + maxDepth);493}494verifyDumpThreads(lockedMonitors, lockedSynchronizers);495return dumpThreads0(null, lockedMonitors, lockedSynchronizers, maxDepth);496}497498// VM support where maxDepth == -1 to request entire stack dump499private static native Thread[] getThreads();500private static native void getThreadInfo1(long[] ids,501int maxDepth,502ThreadInfo[] result);503private static native long getThreadTotalCpuTime0(long id);504private static native void getThreadTotalCpuTime1(long[] ids, long[] result);505private static native long getThreadUserCpuTime0(long id);506private static native void getThreadUserCpuTime1(long[] ids, long[] result);507private static native long getThreadAllocatedMemory0(long id);508private static native void getThreadAllocatedMemory1(long[] ids, long[] result);509private static native void setThreadCpuTimeEnabled0(boolean enable);510private static native void setThreadAllocatedMemoryEnabled0(boolean enable);511private static native void setThreadContentionMonitoringEnabled0(boolean enable);512private static native Thread[] findMonitorDeadlockedThreads0();513private static native Thread[] findDeadlockedThreads0();514private static native void resetPeakThreadCount0();515private static native ThreadInfo[] dumpThreads0(long[] ids,516boolean lockedMonitors,517boolean lockedSynchronizers,518int maxDepth);519520// tid == 0 to reset contention times for all threads521private static native void resetContentionTimes0(long tid);522523public ObjectName getObjectName() {524return Util.newObjectName(ManagementFactory.THREAD_MXBEAN_NAME);525}526527}528529530