Path: blob/master/src/jdk.jconsole/share/classes/sun/tools/jconsole/SummaryTab.java
40948 views
/*1* Copyright (c) 2004, 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.tools.jconsole;2627import java.awt.*;28import java.io.*;29import java.lang.management.*;30import java.lang.reflect.*;31import java.text.*;32import java.util.*;33import java.util.concurrent.*;34import java.util.function.LongSupplier;3536import javax.swing.*;373839import static sun.tools.jconsole.Formatter.*;40import static sun.tools.jconsole.Utilities.*;4142@SuppressWarnings("serial")43class SummaryTab extends Tab {44private static final String cpuUsageKey = "cpu";4546private static final String newDivider = "<tr><td colspan=4><font size =-1><hr>";47private static final String newTable = "<tr><td colspan=4 align=left><table cellpadding=1>";48private static final String newLeftTable = "<tr><td colspan=2 align=left><table cellpadding=1>";49private static final String newRightTable = "<td colspan=2 align=left><table cellpadding=1>";50private static final String endTable = "</table>";5152private static final int CPU_DECIMALS = 1;5354private CPUOverviewPanel overviewPanel;55private DateFormat headerDateTimeFormat;56private String pathSeparator = null;57HTMLPane info;5859private static class Result {60long upTime = -1L;61long processCpuTime = -1L;62long timeStamp;63int nCPUs;64String summary;65}6667public static String getTabName() {68return Messages.SUMMARY_TAB_TAB_NAME;69}7071public SummaryTab(VMPanel vmPanel) {72super(vmPanel, getTabName());7374setLayout(new BorderLayout());7576info = new HTMLPane();77setAccessibleName(info, getTabName());78add(new JScrollPane(info));7980headerDateTimeFormat =81Formatter.getDateTimeFormat(Messages.SUMMARY_TAB_HEADER_DATE_TIME_FORMAT);82}8384public SwingWorker<?, ?> newSwingWorker() {85return new SwingWorker<Result, Object>() {86public Result doInBackground() {87return formatSummary();88}899091protected void done() {92try {93Result result = get();94if (result != null) {95info.setText(result.summary);96if (overviewPanel != null &&97result.upTime > 0L &&98result.processCpuTime >= 0L) {99100overviewPanel.updateCPUInfo(result);101}102}103} catch (InterruptedException ex) {104} catch (ExecutionException ex) {105if (JConsole.isDebug()) {106ex.printStackTrace();107}108}109}110};111}112113StringBuilder buf;114115synchronized Result formatSummary() {116Result result = new Result();117ProxyClient proxyClient = vmPanel.getProxyClient();118if (proxyClient.isDead()) {119return null;120}121122buf = new StringBuilder();123append("<table cellpadding=1>");124125try {126RuntimeMXBean rmBean = proxyClient.getRuntimeMXBean();127CompilationMXBean cmpMBean = proxyClient.getCompilationMXBean();128ThreadMXBean tmBean = proxyClient.getThreadMXBean();129MemoryMXBean memoryBean = proxyClient.getMemoryMXBean();130ClassLoadingMXBean clMBean = proxyClient.getClassLoadingMXBean();131OperatingSystemMXBean osMBean = proxyClient.getOperatingSystemMXBean();132com.sun.management.OperatingSystemMXBean sunOSMBean =133proxyClient.getSunOperatingSystemMXBean();134135append("<tr><td colspan=4>");136append("<center><b>" + Messages.SUMMARY_TAB_TAB_NAME + "</b></center>");137String dateTime =138headerDateTimeFormat.format(System.currentTimeMillis());139append("<center>" + dateTime + "</center>");140141append(newDivider);142143{ // VM info144append(newLeftTable);145append(Messages.CONNECTION_NAME, vmPanel.getDisplayName());146append(Messages.VIRTUAL_MACHINE,147Resources.format(Messages.SUMMARY_TAB_VM_VERSION,148rmBean.getVmName(), rmBean.getVmVersion()));149append(Messages.VENDOR, rmBean.getVmVendor());150append(Messages.NAME, rmBean.getName());151append(endTable);152153append(newRightTable);154result.upTime = rmBean.getUptime();155append(Messages.UPTIME, formatTime(result.upTime));156if (sunOSMBean != null) {157result.processCpuTime = sunOSMBean.getProcessCpuTime();158append(Messages.PROCESS_CPU_TIME, formatNanoTime(result.processCpuTime));159}160161if (cmpMBean != null) {162append(Messages.JIT_COMPILER, cmpMBean.getName());163append(Messages.TOTAL_COMPILE_TIME,164cmpMBean.isCompilationTimeMonitoringSupported()165? formatTime(cmpMBean.getTotalCompilationTime())166: Messages.UNAVAILABLE);167} else {168append(Messages.JIT_COMPILER, Messages.UNAVAILABLE);169}170append(endTable);171}172173append(newDivider);174175{ // Threads and Classes176append(newLeftTable);177int tlCount = tmBean.getThreadCount();178int tdCount = tmBean.getDaemonThreadCount();179int tpCount = tmBean.getPeakThreadCount();180long ttCount = tmBean.getTotalStartedThreadCount();181String[] strings1 = formatLongs(tlCount, tpCount,182tdCount, ttCount);183append(Messages.LIVE_THREADS, strings1[0]);184append(Messages.PEAK, strings1[1]);185append(Messages.DAEMON_THREADS, strings1[2]);186append(Messages.TOTAL_THREADS_STARTED, strings1[3]);187append(endTable);188189append(newRightTable);190long clCount = clMBean.getLoadedClassCount();191long cuCount = clMBean.getUnloadedClassCount();192long ctCount = clMBean.getTotalLoadedClassCount();193String[] strings2 = formatLongs(clCount, cuCount, ctCount);194append(Messages.CURRENT_CLASSES_LOADED, strings2[0]);195append(Messages.TOTAL_CLASSES_LOADED, strings2[2]);196append(Messages.TOTAL_CLASSES_UNLOADED, strings2[1]);197append(null, "");198append(endTable);199}200201append(newDivider);202203{ // Memory204MemoryUsage u = memoryBean.getHeapMemoryUsage();205206append(newLeftTable);207String[] strings1 = formatKByteStrings(u.getUsed(), u.getMax());208append(Messages.CURRENT_HEAP_SIZE, strings1[0]);209append(Messages.MAXIMUM_HEAP_SIZE, strings1[1]);210append(endTable);211212append(newRightTable);213String[] strings2 = formatKByteStrings(u.getCommitted());214append(Messages.COMMITTED_MEMORY, strings2[0]);215append(Messages.SUMMARY_TAB_PENDING_FINALIZATION_LABEL,216Resources.format(Messages.SUMMARY_TAB_PENDING_FINALIZATION_VALUE,217memoryBean.getObjectPendingFinalizationCount()));218append(endTable);219220append(newTable);221Collection<GarbageCollectorMXBean> garbageCollectors =222proxyClient.getGarbageCollectorMXBeans();223for (GarbageCollectorMXBean garbageCollectorMBean : garbageCollectors) {224String gcName = garbageCollectorMBean.getName();225long gcCount = garbageCollectorMBean.getCollectionCount();226long gcTime = garbageCollectorMBean.getCollectionTime();227228append(Messages.GARBAGE_COLLECTOR,229Resources.format(Messages.GC_INFO, gcName, gcCount,230(gcTime >= 0) ? formatTime(gcTime)231: Messages.UNAVAILABLE),2324);233}234append(endTable);235}236237append(newDivider);238239{ // Operating System info240append(newLeftTable);241String osName = osMBean.getName();242String osVersion = osMBean.getVersion();243String osArch = osMBean.getArch();244result.nCPUs = osMBean.getAvailableProcessors();245append(Messages.OPERATING_SYSTEM, osName + " " + osVersion);246append(Messages.ARCHITECTURE, osArch);247append(Messages.NUMBER_OF_PROCESSORS, result.nCPUs+"");248249if (pathSeparator == null) {250// Must use separator of remote OS, not File.pathSeparator251// from this local VM. In the future, consider using252// RuntimeMXBean to get the remote system property.253pathSeparator = osName.startsWith("Windows ") ? ";" : ":";254}255256if (sunOSMBean != null) {257String[] kbStrings1 =258formatKByteStrings(sunOSMBean.getCommittedVirtualMemorySize());259260// getTotalPhysicalMemorySize and getFreePhysicalMemorySize are deprecated,261// but we want be able to get the data for old target VMs (see JDK-8255934).262@SuppressWarnings("deprecation")263String[] kbStrings2 =264formatKByteStrings(tryToGet(sunOSMBean::getTotalMemorySize,265sunOSMBean::getTotalPhysicalMemorySize),266tryToGet(sunOSMBean::getFreeMemorySize,267sunOSMBean::getFreePhysicalMemorySize),268sunOSMBean.getTotalSwapSpaceSize(),269sunOSMBean.getFreeSwapSpaceSize());270271append(Messages.COMMITTED_VIRTUAL_MEMORY, kbStrings1[0]);272append(endTable);273274append(newRightTable);275append(Messages.TOTAL_PHYSICAL_MEMORY, kbStrings2[0]);276append(Messages.FREE_PHYSICAL_MEMORY, kbStrings2[1]);277append(Messages.TOTAL_SWAP_SPACE, kbStrings2[2]);278append(Messages.FREE_SWAP_SPACE, kbStrings2[3]);279}280281append(endTable);282}283284append(newDivider);285286{ // VM arguments and paths287append(newTable);288String args = "";289java.util.List<String> inputArguments = rmBean.getInputArguments();290for (String arg : inputArguments) {291args += arg + " ";292}293append(Messages.VM_ARGUMENTS, args, 4);294append(Messages.CLASS_PATH, rmBean.getClassPath(), 4);295append(Messages.LIBRARY_PATH, rmBean.getLibraryPath(), 4);296append(Messages.BOOT_CLASS_PATH,297rmBean.isBootClassPathSupported()298? rmBean.getBootClassPath()299: Messages.UNAVAILABLE,3004);301append(endTable);302}303} catch (IOException e) {304if (JConsole.isDebug()) {305e.printStackTrace();306}307proxyClient.markAsDead();308return null;309} catch (UndeclaredThrowableException e) {310if (JConsole.isDebug()) {311e.printStackTrace();312}313proxyClient.markAsDead();314return null;315}316317append("</table>");318319result.timeStamp = System.currentTimeMillis();320result.summary = buf.toString();321322return result;323}324325/**326* Tries to get the specified value from the list of suppliers.327* Returns -1 if all suppliers fail.328*/329private long tryToGet(LongSupplier ... getters) {330for (LongSupplier getter : getters) {331try {332return getter.getAsLong();333} catch (UndeclaredThrowableException e) {334}335}336return -1;337}338339private synchronized void append(String str) {340buf.append(str);341}342343void append(String label, String value) {344append(newRow(label, value));345}346347private void append(String label, String value, int columnPerRow) {348if (columnPerRow == 4 && pathSeparator != null) {349value = value.replace(pathSeparator,350"<b></b>" + pathSeparator);351}352append(newRow(label, value, columnPerRow));353}354355OverviewPanel[] getOverviewPanels() {356if (overviewPanel == null) {357overviewPanel = new CPUOverviewPanel();358}359return new OverviewPanel[] { overviewPanel };360}361362private static class CPUOverviewPanel extends OverviewPanel {363private long prevUpTime, prevProcessCpuTime;364365CPUOverviewPanel() {366super(Messages.CPU_USAGE, cpuUsageKey, Messages.CPU_USAGE, Plotter.Unit.PERCENT);367getPlotter().setDecimals(CPU_DECIMALS);368}369370public void updateCPUInfo(Result result) {371if (prevUpTime > 0L && result.upTime > prevUpTime) {372// elapsedCpu is in ns and elapsedTime is in ms.373long elapsedCpu = result.processCpuTime - prevProcessCpuTime;374long elapsedTime = result.upTime - prevUpTime;375// cpuUsage could go higher than 100% because elapsedTime376// and elapsedCpu are not fetched simultaneously. Limit to377// 99% to avoid Plotter showing a scale from 0% to 200%.378float cpuUsage =379Math.min(99F,380elapsedCpu / (elapsedTime * 10000F * result.nCPUs));381382cpuUsage = Math.max(0F, cpuUsage);383384getPlotter().addValues(result.timeStamp,385Math.round(cpuUsage * Math.pow(10.0, CPU_DECIMALS)));386getInfoLabel().setText(Resources.format(Messages.CPU_USAGE_FORMAT,387String.format("%."+CPU_DECIMALS+"f", cpuUsage)));388}389this.prevUpTime = result.upTime;390this.prevProcessCpuTime = result.processCpuTime;391}392}393}394395396