首页 > 编程语言 >Java类MemoryUsage查看虚拟机的使用情况

Java类MemoryUsage查看虚拟机的使用情况

时间:2022-12-26 16:39:35浏览次数:55  
标签:used Java max 虚拟机 MemoryUsage memory new import table

 

Arthas 是阿里巴巴开源的一款监控java进程的工具,可以有效监控CPU、内存使用情况,更厉害的是可以帮助开发人员深入排查java代码的问题,比如java进程占用cpu过高是哪一个线程执行哪一个类的哪一个方法出的问题

首先,先给大家普及一下Arthas的使用步骤:

Step1 下载安装:

在线安装方式: curl -O https://alibaba.github.io/arthas/arthas-boot.jar

离线方式:到github下载对应的已发布的稳定的jar包 https://github.com/alibaba/arthas/tree/arthas-all-3.1.7

Step2 启动:

java -jar arthas-boot.jar

启动成功后如下图所示:

Java类MemoryUsage查看虚拟机的使用情况_arthas

 

上图界面可以看到检测到了16个java进程,其中一个不可用;默认当前会话选中的是第一个进程:3968

如果需要切换到其他进程怎么办呢?

直接输入对应的进程编号即可,如下图所示:

Java类MemoryUsage查看虚拟机的使用情况_java_02

 

 从图中效果可以发现,虽然已经Attach捕获进程成功,但是当前进程还是之前的会话进程3968,这是Arthas的一个坑

很简单解决此问题,如下图所示步骤:

先关闭当前会话,然后再重启arthas,

Java类MemoryUsage查看虚拟机的使用情况_arthas_03

 

 

Java类MemoryUsage查看虚拟机的使用情况_arthas_04

 

 

如此以上两个步骤即可解决这个坑人的问题~~

下面是简单列举下常用的命令:

命令:dashboard 当前系统的实时数据状态看板,线程的cpu占用情况,内存的消耗和垃圾回收情况等

Java类MemoryUsage查看虚拟机的使用情况_sed_05

 

 

命令:sc 查看JVM已加载的类信息

Java类MemoryUsage查看虚拟机的使用情况_arthas_06

 

 命令:sm 查看已加载类的方法信息

Java类MemoryUsage查看虚拟机的使用情况_java_07

 

 

命令:trace 定位方法内部代码块性能耗时情况

Java类MemoryUsage查看虚拟机的使用情况_java_08

 

 命令:thread 显示所有线程的信息

Java类MemoryUsage查看虚拟机的使用情况_arthas_09

 

 

thread -n 3 展示当前最忙的前N个线程并打印堆栈

Java类MemoryUsage查看虚拟机的使用情况_Java_10

 

 

就此为止,想查看更多的命令解释,请参见官方文档
​​​https://alibaba.github.io/arthas/commands.html​​​


Java类MemoryUsage,通过MemoryUsage可以查看Java 虚拟机的内存池的内存使用情况。

MemoryUsage类有四个值(均以字节为单位):

Init:java虚拟机在启动的时候向操作系统请求的初始内存容量,java虚拟机在运行的过程中可能向操作系统请求更多的内存或将内存释放给操作系统,所以init的值是不确定的。

Used:当前已经使用的内存量。

Committed:表示保证java虚拟机能使用的内存量,已提交的内存量可以随时间而变化(增加或减少)。Java 虚拟机可能会将内存释放给系统,committed 可以小于 init。committed 将始终大于或等于 used。

Max:表示可以用于内存管理的最大内存量(以字节为单位)。可以不定义其值。如果定义了该值,最大内存量可能随时间而更改。已使用的内存量和已提 交的内存量将始终小于或等于 max(如果定义了 max)。如果内存分配试图增加满足以下条件的已使用内存将会失败:used > committed,即使 used <= max 仍然为 true(例如,当系统的虚拟内存不足时)。

直接看demo吧!

在实际开发中,一般可以用这个监控线程占用内存使用情况。

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;

public class MemoryUseTest {

public String getMemoryUseInfo(){

MemoryUsage mu = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();

long getCommitted = mu.getCommitted();

long getInit = mu.getInit();

long getUsed = mu.getUsed();

long max = mu.getMax();

return ">>getCommitted(MB)=>" + getCommitted / 1000 / 1000 + "\n"
+">>getInit(MB)=" + getInit / 1000 / 1000 + "\n"
+">>getUsed(MB)=" + getUsed / 1000 / 1000 + "\n"
+">>max(MB)=" + max / 1000 / 1000 + "\n";
}
public static void main(String[] args){
System.out.println(new MemoryUseTest().getMemoryUseInfo());
}
}

JVM中MemoryUsage中init,committed,used,max的含义

package java.lang.management;

import javax.management.openmbean.CompositeData;
import sun.management.MemoryUsageCompositeData;

/**
* A <tt>MemoryUsage</tt> object represents a snapshot of memory usage.
* Instances of the <tt>MemoryUsage</tt> class are usually constructed
* by methods that are used to obtain memory usage
* information about individual memory pool of the Java virtual machine or
* the heap or non-heap memory of the Java virtual machine as a whole.
*
* <p> A <tt>MemoryUsage</tt> object contains four values:
* <table summary="Describes the MemoryUsage object content">
* <tr>
* <td valign=top> <tt>init</tt> </td>
* <td valign=top> represents the initial amount of memory (in bytes) that
* the Java virtual machine requests from the operating system
* for memory management during startup. The Java virtual machine
* may request additional memory from the operating system and
* may also release memory to the system over time.
* The value of <tt>init</tt> may be undefined.
* </td>
* </tr>
* <tr>
* <td valign=top> <tt>used</tt> </td>
* <td valign=top> represents the amount of memory currently used (in bytes).
* </td>
* </tr>
* <tr>
* <td valign=top> <tt>committed</tt> </td>
* <td valign=top> represents the amount of memory (in bytes) that is
* guaranteed to be available for use by the Java virtual machine.
* The amount of committed memory may change over time (increase
* or decrease). The Java virtual machine may release memory to
* the system and <tt>committed</tt> could be less than <tt>init</tt>.
* <tt>committed</tt> will always be greater than
* or equal to <tt>used</tt>.
* </td>
* </tr>
* <tr>
* <td valign=top> <tt>max</tt> </td>
* <td valign=top> represents the maximum amount of memory (in bytes)
* that can be used for memory management. Its value may be undefined.
* The maximum amount of memory may change over time if defined.
* The amount of used and committed memory will always be less than
* or equal to <tt>max</tt> if <tt>max</tt> is defined.
* A memory allocation may fail if it attempts to increase the
* used memory such that <tt>used > committed</tt> even
* if <tt>used <= max</tt> would still be true (for example,
* when the system is low on virtual memory).
* </td>
* </tr>
* </table>
*
* Below is a picture showing an example of a memory pool:
*
* <pre>
* +----------------------------------------------+
* +//////////////// | +
* +//////////////// | +
* +----------------------------------------------+
*
* |--------|
* init
* |---------------|
* used
* |---------------------------|
* committed
* |----------------------------------------------|
* max
* </pre>
*
* <h3>MXBean Mapping</h3>
* <tt>MemoryUsage</tt> is mapped to a {@link CompositeData CompositeData}
* with attributes as specified in the {@link #from from} method.
*
* @author Mandy Chung
* @since 1.5
*/
public class MemoryUsage {
private final long init;
private final long used;
private final long committed;
private final long max;

/**
* Constructs a <tt>MemoryUsage</tt> object.
*
* @param init the initial amount of memory in bytes that
* the Java virtual machine allocates;
* or <tt>-1</tt> if undefined.
* @param used the amount of used memory in bytes.
* @param committed the amount of committed memory in bytes.
* @param max the maximum amount of memory in bytes that
* can be used; or <tt>-1</tt> if undefined.
*
* @throws IllegalArgumentException if
* <ul>
* <li> the value of <tt>init</tt> or <tt>max</tt> is negative
* but not <tt>-1</tt>; or</li>
* <li> the value of <tt>used</tt> or <tt>committed</tt> is negative;
* or</li>
* <li> <tt>used</tt> is greater than the value of <tt>committed</tt>;
* or</li>
* <li> <tt>committed</tt> is greater than the value of <tt>max</tt>
* <tt>max</tt> if defined.</li>
* </ul>
*/
public MemoryUsage(long init,
long used,
long committed,
long max) {
if (init < -1) {
throw new IllegalArgumentException( "init parameter = " +
init + " is negative but not -1.");
}
if (max < -1) {
throw new IllegalArgumentException( "max parameter = " +
max + " is negative but not -1.");
}
if (used < 0) {
throw new IllegalArgumentException( "used parameter = " +
used + " is negative.");
}
if (committed < 0) {
throw new IllegalArgumentException( "committed parameter = " +
committed + " is negative.");
}
if (used > committed) {
throw new IllegalArgumentException( "used = " + used +
" should be <= committed = " + committed);
}
if (max >= 0 && committed > max) {
throw new IllegalArgumentException( "committed = " + committed +
" should be < max = " + max);
}

this.init = init;
this.used = used;
this.committed = committed;
this.max = max;
}

/**
* Constructs a <tt>MemoryUsage</tt> object from a
* {@link CompositeData CompositeData}.
*/
private MemoryUsage(CompositeData cd) {
// validate the input composite data
MemoryUsageCompositeData.validateCompositeData(cd);

this.init = MemoryUsageCompositeData.getInit(cd);
this.used = MemoryUsageCompositeData.getUsed(cd);
this.committed = MemoryUsageCompositeData.getCommitted(cd);
this.max = MemoryUsageCompositeData.getMax(cd);
}

/**
* Returns the amount of memory in bytes that the Java virtual machine
* initially requests from the operating system for memory management.
* This method returns <tt>-1</tt> if the initial memory size is undefined.
*
* @return the initial size of memory in bytes;
* <tt>-1</tt> if undefined.
*/
public long getInit() {
return init;
}

/**
* Returns the amount of used memory in bytes.
*
* @return the amount of used memory in bytes.
*
*/
public long getUsed() {
return used;
};

/**
* Returns the amount of memory in bytes that is committed for
* the Java virtual machine to use. This amount of memory is
* guaranteed for the Java virtual machine to use.
*
* @return the amount of committed memory in bytes.
*
*/
public long getCommitted() {
return committed;
};

/**
* Returns the maximum amount of memory in bytes that can be
* used for memory management. This method returns <tt>-1</tt>
* if the maximum memory size is undefined.
*
* <p> This amount of memory is not guaranteed to be available
* for memory management if it is greater than the amount of
* committed memory. The Java virtual machine may fail to allocate
* memory even if the amount of used memory does not exceed this
* maximum size.
*
* @return the maximum amount of memory in bytes;
* <tt>-1</tt> if undefined.
*/
public long getMax() {
return max;
};

/**
* Returns a descriptive representation of this memory usage.
*/
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("init = " + init + "(" + (init >> 10) + "K) ");
buf.append("used = " + used + "(" + (used >> 10) + "K) ");
buf.append("committed = " + committed + "(" +
(committed >> 10) + "K) " );
buf.append("max = " + max + "(" + (max >> 10) + "K)");
return buf.toString();
}

/**
* Returns a <tt>MemoryUsage</tt> object represented by the
* given <tt>CompositeData</tt>. The given <tt>CompositeData</tt>
* must contain the following attributes:
*
* <blockquote>
* <table border summary="The attributes and the types the given CompositeData contains">
* <tr>
* <th align=left>Attribute Name</th>
* <th align=left>Type</th>
* </tr>
* <tr>
* <td>init</td>
* <td><tt>java.lang.Long</tt></td>
* </tr>
* <tr>
* <td>used</td>
* <td><tt>java.lang.Long</tt></td>
* </tr>
* <tr>
* <td>committed</td>
* <td><tt>java.lang.Long</tt></td>
* </tr>
* <tr>
* <td>max</td>
* <td><tt>java.lang.Long</tt></td>
* </tr>
* </table>
* </blockquote>
*
* @param cd <tt>CompositeData</tt> representing a <tt>MemoryUsage</tt>
*
* @throws IllegalArgumentException if <tt>cd</tt> does not
* represent a <tt>MemoryUsage</tt> with the attributes described
* above.
*
* @return a <tt>MemoryUsage</tt> object represented by <tt>cd</tt>
* if <tt>cd</tt> is not <tt>null</tt>;
* <tt>null</tt> otherwise.
*/
public static MemoryUsage from(CompositeData cd) {
if (cd == null) {
return null;
}

if (cd instanceof MemoryUsageCompositeData) {
return ((MemoryUsageCompositeData) cd).getMemoryUsage();
} else {
return new MemoryUsage(cd);
}

}
}

jdk 1.8.0_191

 

 

Java类MemoryUsage查看虚拟机的使用情况_java_11

 

package com.taobao.arthas.core.command.monitor200;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.taobao.arthas.core.command.Constants;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.shell.handlers.Handler;
import com.taobao.arthas.core.shell.handlers.shell.QExitHandler;
import com.taobao.arthas.core.shell.session.Session;
import com.taobao.arthas.core.util.LogUtil;
import com.taobao.arthas.core.util.NetUtils;
import com.taobao.arthas.core.util.NetUtils.Response;
import com.taobao.arthas.core.util.ThreadUtil;
import com.taobao.arthas.core.util.metrics.SumRateCounter;
import com.taobao.middleware.cli.annotations.Description;
import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Option;
import com.taobao.middleware.cli.annotations.Summary;
import com.taobao.middleware.logger.Logger;
import com.taobao.text.Color;
import com.taobao.text.Decoration;
import com.taobao.text.Style;
import com.taobao.text.renderers.ThreadRenderer;
import com.taobao.text.ui.RowElement;
import com.taobao.text.ui.TableElement;
import com.taobao.text.util.RenderUtil;

import java.lang.management.BufferPoolMXBean;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryType;
import java.lang.management.MemoryUsage;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

/**
* @author hengyunabc 2015年11月19日 上午11:57:21
*/
@Name("dashboard")
@Summary("Overview of target jvm's thread, memory, gc, vm, tomcat info.")
@Description(Constants.EXAMPLE +
" dashboard\n" +
" dashboard -n 10\n" +
" dashboard -i 2000\n" +
Constants.WIKI + Constants.WIKI_HOME + "dashboard")
public class DashboardCommand extends AnnotatedCommand {

private static final Logger logger = LogUtil.getArthasLogger();

private SumRateCounter tomcatRequestCounter = new SumRateCounter();
private SumRateCounter tomcatErrorCounter = new SumRateCounter();
private SumRateCounter tomcatReceivedBytesCounter = new SumRateCounter();
private SumRateCounter tomcatSentBytesCounter = new SumRateCounter();

private int numOfExecutions = Integer.MAX_VALUE;

private boolean batchMode;

private long interval = 5000;

private volatile long count = 0;
private volatile Timer timer;

@Option(shortName = "n", longName = "number-of-execution")
@Description("The number of times this command will be executed.")
public void setNumOfExecutions(int numOfExecutions) {
this.numOfExecutions = numOfExecutions;
}

@Option(shortName = "b", longName = "batch")
@Description("Execute this command in batch mode.")
public void setBatchMode(boolean batchMode) {
this.batchMode = batchMode;
}

@Option(shortName = "i", longName = "interval")
@Description("The interval (in ms) between two executions, default is 5000 ms.")
public void setInterval(long interval) {
this.interval = interval;
}


@Override
public void process(final CommandProcess process) {

Session session = process.session();
timer = new Timer("Timer-for-arthas-dashboard-" + session.getSessionId(), true);

// ctrl-C support
process.interruptHandler(new DashboardInterruptHandler(process, timer));

/*
* 通过handle回调,在suspend和end时停止timer,resume时重启timer
*/
Handler<Void> stopHandler = new Handler<Void>() {
@Override
public void handle(Void event) {
stop();
}
};

Handler<Void> restartHandler = new Handler<Void>() {
@Override
public void handle(Void event) {
restart(process);
}
};
process.suspendHandler(stopHandler);
process.resumeHandler(restartHandler);
process.endHandler(stopHandler);

// q exit support
process.stdinHandler(new QExitHandler(process));

// start the timer
timer.scheduleAtFixedRate(new DashboardTimerTask(process), 0, getInterval());
}

public synchronized void stop() {
if (timer != null) {
timer.cancel();
timer.purge();
timer = null;
}
}

public synchronized void restart(CommandProcess process) {
if (timer == null) {
Session session = process.session();
timer = new Timer("Timer-for-arthas-dashboard-" + session.getSessionId(), true);
timer.scheduleAtFixedRate(new DashboardTimerTask(process), 0, getInterval());
}
}

public int getNumOfExecutions() {
return numOfExecutions;
}

public boolean isBatchMode() {
return batchMode;
}

public long getInterval() {
return interval;
}

private static String beautifyName(String name) {
return name.replace(' ', '_').toLowerCase();
}

private static void addBufferPoolMemoryInfo(TableElement table) {
try {
@SuppressWarnings("rawtypes")
Class bufferPoolMXBeanClass = Class.forName("java.lang.management.BufferPoolMXBean");
@SuppressWarnings("unchecked")
List<BufferPoolMXBean> bufferPoolMXBeans = ManagementFactory.getPlatformMXBeans(bufferPoolMXBeanClass);
for (BufferPoolMXBean mbean : bufferPoolMXBeans) {
long used = mbean.getMemoryUsed();
long total = mbean.getTotalCapacity();
new MemoryEntry(mbean.getName(), used, total, Long.MIN_VALUE).addTableRow(table);
}
} catch (ClassNotFoundException e) {
// ignore
}
}

private static void addRuntimeInfo(TableElement table) {
table.row("os.name", System.getProperty("os.name"));
table.row("os.version", System.getProperty("os.version"));
table.row("java.version", System.getProperty("java.version"));
table.row("java.home", System.getProperty("java.home"));
table.row("systemload.average",
String.format("%.2f", ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage()));
table.row("processors", "" + Runtime.getRuntime().availableProcessors());
table.row("uptime", "" + ManagementFactory.getRuntimeMXBean().getUptime() / 1000 + "s");
}

private static void addMemoryInfo(TableElement table) {
MemoryUsage heapMemoryUsage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
MemoryUsage nonHeapMemoryUsage = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();

List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans();

new MemoryEntry("heap", heapMemoryUsage).addTableRow(table, Decoration.bold.bold());
for (MemoryPoolMXBean poolMXBean : memoryPoolMXBeans) {
if (MemoryType.HEAP.equals(poolMXBean.getType())) {
MemoryUsage usage = poolMXBean.getUsage();
String poolName = beautifyName(poolMXBean.getName());
new MemoryEntry(poolName, usage).addTableRow(table);
}
}

new MemoryEntry("nonheap", nonHeapMemoryUsage).addTableRow(table, Decoration.bold.bold());
for (MemoryPoolMXBean poolMXBean : memoryPoolMXBeans) {
if (MemoryType.NON_HEAP.equals(poolMXBean.getType())) {
MemoryUsage usage = poolMXBean.getUsage();
String poolName = beautifyName(poolMXBean.getName());
new MemoryEntry(poolName, usage).addTableRow(table);
}
}

addBufferPoolMemoryInfo(table);
}

private static void addGcInfo(TableElement table) {
List<GarbageCollectorMXBean> garbageCollectorMxBeans = ManagementFactory.getGarbageCollectorMXBeans();
for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorMxBeans) {
String name = garbageCollectorMXBean.getName();
table.add(new RowElement().style(Decoration.bold.bold()).add("gc." + beautifyName(name) + ".count",
"" + garbageCollectorMXBean.getCollectionCount()));
table.row("gc." + beautifyName(name) + ".time(ms)", "" + garbageCollectorMXBean.getCollectionTime());
}
}

private static String formatBytes(long size) {
int unit = 1;
String unitStr = "B";
if (size / 1024 > 0) {
unit = 1024;
unitStr = "K";
} else if (size / 1024 / 1024 > 0) {
unit = 1024 * 1024;
unitStr = "M";
}

return String.format("%d%s", size / unit, unitStr);
}

private void addTomcatInfo(TableElement table) {

String threadPoolPath = "http://localhost:8006/connector/threadpool";
String connectorStatPath = "http://localhost:8006/connector/stats";
Response connectorStatResponse = NetUtils.request(connectorStatPath);
if (connectorStatResponse.isSuccess()) {
List<JSONObject> connectorStats = JSON.parseArray(connectorStatResponse.getContent(), JSONObject.class);
for (JSONObject stat : connectorStats) {
String name = stat.getString("name").replace("\"", "");
long bytesReceived = stat.getLongValue("bytesReceived");
long bytesSent = stat.getLongValue("bytesSent");
long processingTime = stat.getLongValue("processingTime");
long requestCount = stat.getLongValue("requestCount");
long errorCount = stat.getLongValue("errorCount");

tomcatRequestCounter.update(requestCount);
tomcatErrorCounter.update(errorCount);
tomcatReceivedBytesCounter.update(bytesReceived);
tomcatSentBytesCounter.update(bytesSent);

table.add(new RowElement().style(Decoration.bold.bold()).add("connector", name));
table.row("QPS", String.format("%.2f", tomcatRequestCounter.rate()));
table.row("RT(ms)", String.format("%.2f", processingTime / (double) requestCount));
table.row("error/s", String.format("%.2f", tomcatErrorCounter.rate()));
table.row("received/s", formatBytes((long) tomcatReceivedBytesCounter.rate()));
table.row("sent/s", formatBytes((long) tomcatSentBytesCounter.rate()));
}
}

Response threadPoolResponse = NetUtils.request(threadPoolPath);
if (threadPoolResponse.isSuccess()) {
List<JSONObject> threadPoolInfos = JSON.parseArray(threadPoolResponse.getContent(), JSONObject.class);
for (JSONObject info : threadPoolInfos) {
String name = info.getString("name").replace("\"", "");
long busy = info.getLongValue("threadBusy");
long total = info.getLongValue("threadCount");
table.add(new RowElement().style(Decoration.bold.bold()).add("threadpool", name));
table.row("busy", "" + busy);
table.row("total", "" + total);
}
}
}

static String drawThreadInfo(int width, int height) {
Map<String, Thread> threads = ThreadUtil.getThreads();
return RenderUtil.render(threads.values().iterator(), new ThreadRenderer(), width, height);
}

static String drawMemoryInfoAndGcInfo(int width, int height) {
TableElement table = new TableElement(1, 1);

TableElement memoryInfoTable = new TableElement(3, 1, 1, 1, 1).rightCellPadding(1);
memoryInfoTable.add(new RowElement().style(Decoration.bold.fg(Color.black).bg(Color.white)).add("Memory",
"used", "total", "max", "usage"));

addMemoryInfo(memoryInfoTable);

TableElement gcInfoTable = new TableElement(1, 1).rightCellPadding(1);
gcInfoTable.add(new RowElement().style(Decoration.bold.fg(Color.black).bg(Color.white)).add("GC", ""));
addGcInfo(gcInfoTable);

table.row(memoryInfoTable, gcInfoTable);
return RenderUtil.render(table, width, height);
}

String drawRuntineInfoAndTomcatInfo(int width, int height) {
TableElement table = new TableElement(1, 1);

TableElement runtimeInfoTable = new TableElement(1, 1).rightCellPadding(1);
runtimeInfoTable
.add(new RowElement().style(Decoration.bold.fg(Color.black).bg(Color.white)).add("Runtime", ""));

addRuntimeInfo(runtimeInfoTable);

TableElement tomcatInfoTable = new TableElement(1, 1).rightCellPadding(1);

try {
// 如果请求tomcat信息失败,则不显示tomcat信息
if (NetUtils.request("http://localhost:8006").isSuccess()) {
tomcatInfoTable
.add(new RowElement().style(Decoration.bold.fg(Color.black).bg(Color.white)).add("Tomcat", ""));
addTomcatInfo(tomcatInfoTable);
}
} catch (Throwable t) {
logger.error(null, "get Tomcat Info error!", t);
}

table.row(runtimeInfoTable, tomcatInfoTable);
return RenderUtil.render(table, width, height);
}

static class MemoryEntry {
String name;
long used;
long total;
long max;

int unit;
String unitStr;

public MemoryEntry(String name, long used, long total, long max) {
this.name = name;
this.used = used;
this.total = total;
this.max = max;

unitStr = "K";
unit = 1024;
if (used / 1024 / 1024 > 0) {
unitStr = "M";
unit = 1024 * 1024;
}
}

public MemoryEntry(String name, MemoryUsage usage) {
this(name, usage.getUsed(), usage.getCommitted(), usage.getMax());
}

private String format(long value) {
String valueStr = "-";
if (value == -1) {
return "-1";
}
if (value != Long.MIN_VALUE) {
valueStr = value / unit + unitStr;
}
return valueStr;
}

public void addTableRow(TableElement table) {
double usage = used / (double) (max == -1 || max == Long.MIN_VALUE ? total : max) * 100;

table.row(name, format(used), format(total), format(max), String.format("%.2f%%", usage));
}

public void addTableRow(TableElement table, Style.Composite style) {
double usage = used / (double) (max == -1 || max == Long.MIN_VALUE ? total : max) * 100;

table.add(new RowElement().style(style).add(name, format(used), format(total), format(max),
String.format("%.2f%%", usage)));
}
}

private class DashboardTimerTask extends TimerTask {
private CommandProcess process;

public DashboardTimerTask(CommandProcess process) {
this.process = process;
}

@Override
public void run() {
if (count >= getNumOfExecutions()) {
// stop the timer
timer.cancel();
timer.purge();
process.write("Process ends after " + getNumOfExecutions() + " time(s).\n");
process.end();
return;
}

int width = process.width();
int height = process.height();

// 上半部分放thread top。下半部分再切分为田字格,其中上面两格放memory, gc的信息。下面两格放tomcat,
// runtime的信息
int totalHeight = height - 1;
int threadTopHeight = totalHeight / 2;
int lowerHalf = totalHeight - threadTopHeight;

int runtimeInfoHeight = lowerHalf / 2;
int heapInfoHeight = lowerHalf - runtimeInfoHeight;

String threadInfo = drawThreadInfo(width, threadTopHeight);
String memoryAndGc = drawMemoryInfoAndGcInfo(width, runtimeInfoHeight);
String runTimeAndTomcat = drawRuntineInfoAndTomcatInfo(width, heapInfoHeight);

process.write(threadInfo + memoryAndGc + runTimeAndTomcat);

count++;
process.times().incrementAndGet();
}
}
}

 com.taobao.arthas.core.command.monitor200.DashboardCommand

 

 

 



标签:used,Java,max,虚拟机,MemoryUsage,memory,new,import,table
From: https://blog.51cto.com/u_15147537/5969300

相关文章

  • https Java SSL Exception protocol_version
      在java代码中,使用HttpClient爬取https页面时,遇到了这个bug:javax.net.ssl.SSLException:Receivedfatalalert:protocol_version     先奉上初始的代码:1/**2......
  • javascript使用正则表达式替换或者捕获子字符串
    letstring='mutiFile[{"name":"新建文件夹(2).zip","ext":".zip","size":1675876,"path":"/static/upload/2022December/ba145698fcc99fd414f0f4ec6ea418e5.zip"}]';......
  • java获取stream流
    java获取stream流可以通过以下四种方式获取1通过list集合获取,list.stream()List<String>list=newArrayList<>();list.add("北京");list.add("上海");list.add("......
  • 阿里巴巴2020届秋招最后一班车 企业智能事业部 企业大脑技术部 2020届秋招 Java 开发
    阿里巴巴企业智能事业部企业大脑技术部2020届秋招-JAVA工程师阿里巴巴企业智能事业部,2020年秋季校招最后一班车啦:JAVA开发工程师虚位以待,机会难得,占坑抓紧。入职就发师兄,一......
  • idea java开发给方法上加注释
    打开IDEA开发工具,file->setting->Editor->LiveTemplates点加号选择templategroup随便起一个名字点击加号,选择LiveTemplate依次填上红框中的......
  • JavaScript中的宏任务和微任务
    在JavaScript中,宏任务和微任务是指在执行代码的过程中的两种不同的任务类型。宏任务(macrotask)指的是浏览器在执行代码的过程中会调度的任务,比如事件循环中的每一次迭代......
  • java基础学习
    数据类型强类型语言要求变量的使用要严格符合规定,所有变量必须先定义再使用java基本数据类型基本类型(primitivetype)数值类型整型byte,short,int,long;......
  • Java双亲委派模型:为什么要双亲委派?如何打破它?破在哪里?---todo
    文章目录一、前言二、类加载器三、双亲委派机制1、什么是双亲委派2、为什么要双亲委派?四、破坏双亲委派1、直接自定义类加载器加载2、跳过AppClassLoader和ExtClas......
  • JavaScript学习--Item30 数组进阶全掌握
    在程序语言中数组的重要性不言而喻,JavaScript中数组也是最常使用的对象之一,数组是值的有序集合,由于弱类型的原因,JavaScript中数组十分灵活、强大,不像是Java等强类型高级语......
  • Java基础知识总结
    Java​​C​​C++​​C#​​OS ​​JVM​​W3CJAVA教程​JAVA考古学​​StringBuffer和StringBuilder中的两个函数://int indexOf(String......