Repository navigation
jcmd jstat
wangkaiwu edited this page Jun 26, 2022
·
2 revisions
$ jstat -gc 4349
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT CGC CGCT GCT
22016.0 12800.0 0.0 12370.4 125952.0 124167.3 182272.0 22049.5 58112.0 54113.0 8448.0 7736.6 9 0.158 2 0.051 - - 0.209public class Jstat {
private static Arguments arguments;
public static void main(String[] args) {
arguments = new Arguments(args);
if (arguments.isOptions()) {
OptionLister ol = new OptionLister(arguments.optionsSources());
ol.print(System.out);
System.exit(0);
}
logSamples();
}
}public class Arguments {
private boolean help;
public Arguments(String[] args) throws IllegalArgumentException {
int argc = 0;
if (args.length == 0) {
help = true;
return;
}
if (args[0].compareTo("-options") == 0) {
options = true;
return;
} else if (args[0].compareTo("-list") == 0) {
list = true;
argc++;
}
switch (args.length - argc) {
case 3:
interval = toMillis(args[args.length - 2]);
vmIdString = args[args.length - 3];
break;
case 2:
interval = toMillis(args[args.length - 1]);
vmIdString = args[args.length - 2];
case 1:
vmIdString = args[args.length - 1];
break;
}
if (count == -1 && interval == -1) {
count = 1;
interval = 0;
}
vmId = new VmIdentifier(vmIdString);
}
}public class JStat {
static void logSamples() throws MonitorException {
// jvm 进程Id
final VmIdentifier vmId = arguments.vmId();
// 间隔时间
int interval = arguments.sampleInterval();
final MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);
MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, interval);
final JStatLogger logger = new JStatLogger(monitoredVm);
OutputFormatter formatter = null;
if (arguments.isSpecialOption()) {
OptionFormat format = arguments.optionFormat();
formatter = new OptionOutputFormatter(monitoredVm, format);
}
logger.logSamples(formatter, arguments.headerRate(),
arguments.sampleInterval(), arguments.sampleCount(),
System.out);
monitoredHost.detach(monitoredVm);
}
}在 jdk.jcmd 包下有个 resource 目录,里面有个 jstat_options,记录了每个命令的 header
public class JStatLogger {
public void logSamples(OutputFormatter formatter, int headerRate,
int sampleInterval, int sampleCount, PrintStream out)
throws MonitorException {
int printHeader = headerRate;
if (printHeader == 0) {
// 打印命令对应的 header
out.println(formatter.getHeader());
printHeader = -1;
}
while (active) {
// 由于内容是一行一行显示的,所以很容易导致看不到 header了
// 这里就是每隔几行就打印一下 header
if (printHeader > 0 && --printHeaderCount <= 0) {
printHeaderCount = printHeader;
out.println(formatter.getHeader());
}
out.println(formatter.getRow());
// sampleCount 是共计采样数量,如果超限了就退出
if (sampleCount > 0 && ++iterationCount >= sampleCount) {
break;
}
// 定时触发
Thread.sleep(sampleInterval);
}
}
}public class MonitoredHostProvider extends MonitoredHost {
public MonitoredVm getMonitoredVm(VmIdentifier vmid, int interval)
throws MonitorException {
VmIdentifier nvmid = hostId.resolve(vmid);
return new LocalMonitoredVm(nvmid, interval);
}
}public class LocalMonitoredVm extends AbstractMonitoredVm {
public LocalMonitoredVm(VmIdentifier vmid, int interval) throws MonitorException {
super(vmid, interval);
this.pdb = new PerfDataBuffer(vmid);
listeners = new ArrayList<VmListener>();
}
}public class PerfDataBuffer extends AbstractPerfDataBuffer {
public PerfDataBuffer(VmIdentifier vmid) throws MonitorException {
ByteBuffer bb = perf.attach(vmid.getLocalVmId(), vmid.getMode());
createPerfDataBuffer(bb, vmid.getLocalVmId());
}
}public class RowClosure implements Closure {
private MonitoredVm vm;
private StringBuilder row = new StringBuilder();
public void visit(Object o, boolean hasNext) throws MonitorException {
ColumnFormat c = (ColumnFormat) o;
String s = null;
Expression e = c.getExpression();
ExpressionEvaluator ee = new ExpressionExecuter(vm);
Object value = ee.evaluate(e);
if (value instanceof String) {
s = (String) value;
} else if (value instanceof Number) {
double d = ((Number) value).doubleValue();
double scaledValue = c.getScale().scale(d);
s = df.format(scaledValue);
}
s = c.getAlignment().align(s, c.getWidth());
row.append(s);
if (hasNext) {
row.append(" ");
}
}
}public class ExpressionExecuter implements ExpressionEvaluator {
public Object evaluate(Expression e) {
if (e instanceof Literal) {
return ((Literal) e).getValue();
}
if (e instanceof Identifier) {
Identifier id = (Identifier) e;
if (map.containsKey(id.getName())) {
return map.get(id.getName());
} else {
Monitor m = (Monitor) id.getValue();
Object v = m.getValue();
map.put(id.getName(), v);
return v;
}
}
Expression l = e.getLeft();
Expression r = e.getRight();
Operator op = e.getOperator();
if (op == null) {
return evaluate(l);
} else {
double lval = ((Number) evaluate(l)).doubleValue();
double rval = ((Number) evaluate(r)).doubleValue();
double result = op.eval(lval, rval);
return Double.valueOf(result);
}
}
}public class RowClosure implements Closure {
public void visit(Object o, boolean hasNext) throws MonitorException {
ColumnFormat c = (ColumnFormat)o;
Expression e = c.getExpression();
}
}public class Parser {
private void dataStmt(ColumnFormat cf) throws ParserException, IOException {
match(DATA);
Expression e = expression();
// 上面的 getExpression() 对应的就是这里的 setExpression()
cf.setExpression(e);
}
private Expression expression() throws ParserException, IOException {
Expression e = addExpression();
return e;
}
private Expression addExpression() throws ParserException, IOException {
Expression e = multExpression();
Operator op = null;
while (true) {
switch (lookahead.ttype) {
case OPERATOR_PLUS:
match(OPERATOR_PLUS);
op = Operator.PLUS;
break;
case OPERATOR_MINUS:
match(OPERATOR_MINUS);
op = Operator.MINUS;
break;
default:
return e;
}
Expression e1 = new Expression();
e1.setOperator(op);
e1.setLeft(e);
e1.setRight(multExpression());
e = e1;
}
}
}enum CounterNS {
JAVA_NS,
COM_NS,
SUN_NS,
}