Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/demo/management/FullThreadDump/ThreadMonitor.java
38829 views
/*1* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions5* are met:6*7* - Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9*10* - Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* - Neither the name of Oracle nor the names of its15* contributors may be used to endorse or promote products derived16* from this software without specific prior written permission.17*18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS19* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,20* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR21* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR22* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,23* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,24* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR25* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF26* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING27* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS28* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29*/3031/*32* This source code is provided to illustrate the usage of a given feature33* or technique and has been deliberately simplified. Additional steps34* required for a production-quality application, such as security checks,35* input validation and proper error handling, might not be present in36* this sample code.37*/383940/*41*/4243import static java.lang.management.ManagementFactory.*;44import java.lang.management.ThreadMXBean;45import java.lang.management.ThreadInfo;46import java.lang.management.LockInfo;47import java.lang.management.MonitorInfo;48import javax.management.*;49import java.io.*;5051/**52* Example of using the java.lang.management API to dump stack trace53* and to perform deadlock detection.54*55* @author Mandy Chung56*/57public class ThreadMonitor {58private MBeanServerConnection server;59private ThreadMXBean tmbean;60private ObjectName objname;6162// default - JDK 6+ VM63private String findDeadlocksMethodName = "findDeadlockedThreads";64private boolean canDumpLocks = true;6566/**67* Constructs a ThreadMonitor object to get thread information68* in a remote JVM.69*/70public ThreadMonitor(MBeanServerConnection server) throws IOException {71this.server = server;72this.tmbean = newPlatformMXBeanProxy(server,73THREAD_MXBEAN_NAME,74ThreadMXBean.class);75try {76objname = new ObjectName(THREAD_MXBEAN_NAME);77} catch (MalformedObjectNameException e) {78// should not reach here79InternalError ie = new InternalError(e.getMessage());80ie.initCause(e);81throw ie;82}83parseMBeanInfo();84}8586/**87* Constructs a ThreadMonitor object to get thread information88* in the local JVM.89*/90public ThreadMonitor() {91this.tmbean = getThreadMXBean();92}9394/**95* Prints the thread dump information to System.out.96*/97public void threadDump() {98if (canDumpLocks) {99if (tmbean.isObjectMonitorUsageSupported() &&100tmbean.isSynchronizerUsageSupported()) {101// Print lock info if both object monitor usage102// and synchronizer usage are supported.103// This sample code can be modified to handle if104// either monitor usage or synchronizer usage is supported.105dumpThreadInfoWithLocks();106}107} else {108dumpThreadInfo();109}110}111112private void dumpThreadInfo() {113System.out.println("Full Java thread dump");114long[] tids = tmbean.getAllThreadIds();115ThreadInfo[] tinfos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE);116for (ThreadInfo ti : tinfos) {117printThreadInfo(ti);118}119}120121/**122* Prints the thread dump information with locks info to System.out.123*/124private void dumpThreadInfoWithLocks() {125System.out.println("Full Java thread dump with locks info");126127ThreadInfo[] tinfos = tmbean.dumpAllThreads(true, true);128for (ThreadInfo ti : tinfos) {129printThreadInfo(ti);130LockInfo[] syncs = ti.getLockedSynchronizers();131printLockInfo(syncs);132}133System.out.println();134}135136private static String INDENT = " ";137138private void printThreadInfo(ThreadInfo ti) {139// print thread information140printThread(ti);141142// print stack trace with locks143StackTraceElement[] stacktrace = ti.getStackTrace();144MonitorInfo[] monitors = ti.getLockedMonitors();145for (int i = 0; i < stacktrace.length; i++) {146StackTraceElement ste = stacktrace[i];147System.out.println(INDENT + "at " + ste.toString());148for (MonitorInfo mi : monitors) {149if (mi.getLockedStackDepth() == i) {150System.out.println(INDENT + " - locked " + mi);151}152}153}154System.out.println();155}156157private void printThread(ThreadInfo ti) {158StringBuilder sb = new StringBuilder("\"" + ti.getThreadName() + "\"" +159" Id=" + ti.getThreadId() +160" in " + ti.getThreadState());161if (ti.getLockName() != null) {162sb.append(" on lock=" + ti.getLockName());163}164if (ti.isSuspended()) {165sb.append(" (suspended)");166}167if (ti.isInNative()) {168sb.append(" (running in native)");169}170System.out.println(sb.toString());171if (ti.getLockOwnerName() != null) {172System.out.println(INDENT + " owned by " + ti.getLockOwnerName() +173" Id=" + ti.getLockOwnerId());174}175}176177private void printMonitorInfo(ThreadInfo ti) {178MonitorInfo[] monitors = ti.getLockedMonitors();179System.out.println(INDENT + "Locked monitors: count = " + monitors.length);180for (MonitorInfo mi : monitors) {181System.out.println(INDENT + " - " + mi + " locked at ");182System.out.println(INDENT + " " + mi.getLockedStackDepth() +183" " + mi.getLockedStackFrame());184}185}186187private void printLockInfo(LockInfo[] locks) {188System.out.println(INDENT + "Locked synchronizers: count = " + locks.length);189for (LockInfo li : locks) {190System.out.println(INDENT + " - " + li);191}192System.out.println();193}194195/**196* Checks if any threads are deadlocked. If any, print197* the thread dump information.198*/199public boolean findDeadlock() {200long[] tids;201if (findDeadlocksMethodName.equals("findDeadlockedThreads") &&202tmbean.isSynchronizerUsageSupported()) {203tids = tmbean.findDeadlockedThreads();204if (tids == null) {205return false;206}207208System.out.println("Deadlock found :-");209ThreadInfo[] infos = tmbean.getThreadInfo(tids, true, true);210for (ThreadInfo ti : infos) {211printThreadInfo(ti);212printMonitorInfo(ti);213printLockInfo(ti.getLockedSynchronizers());214System.out.println();215}216} else {217tids = tmbean.findMonitorDeadlockedThreads();218if (tids == null) {219return false;220}221ThreadInfo[] infos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE);222for (ThreadInfo ti : infos) {223// print thread information224printThreadInfo(ti);225}226}227228return true;229}230231232private void parseMBeanInfo() throws IOException {233try {234MBeanOperationInfo[] mopis = server.getMBeanInfo(objname).getOperations();235236// look for findDeadlockedThreads operations;237boolean found = false;238for (MBeanOperationInfo op : mopis) {239if (op.getName().equals(findDeadlocksMethodName)) {240found = true;241break;242}243}244if (!found) {245// if findDeadlockedThreads operation doesn't exist,246// the target VM is running on JDK 5 and details about247// synchronizers and locks cannot be dumped.248findDeadlocksMethodName = "findMonitorDeadlockedThreads";249canDumpLocks = false;250}251} catch (IntrospectionException e) {252InternalError ie = new InternalError(e.getMessage());253ie.initCause(e);254throw ie;255} catch (InstanceNotFoundException e) {256InternalError ie = new InternalError(e.getMessage());257ie.initCause(e);258throw ie;259} catch (ReflectionException e) {260InternalError ie = new InternalError(e.getMessage());261ie.initCause(e);262throw ie;263}264}265}266267268