profiler command support live/sched/cstack/begin/end/ttsp options (#2657)

pull/2661/head
Winson Huang 1 year ago committed by GitHub
parent 69cdf83181
commit 910b578f25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -81,6 +81,11 @@ public class ProfilerCommand extends AnnotatedCommand {
*/ */
private String alloc; private String alloc;
/**
* build allocation profile from live objects only
*/
private boolean live;
/** /**
* profile contended locks longer than DURATION ns * profile contended locks longer than DURATION ns
* according to async-profiler README, alloc may contains non-numeric charactors * according to async-profiler README, alloc may contains non-numeric charactors
@ -112,6 +117,17 @@ public class ProfilerCommand extends AnnotatedCommand {
*/ */
private boolean threads; private boolean threads;
/**
* group threads by scheduling policy
*/
private boolean sched;
/**
* how to collect C stack frames in addition to Java stack
* MODE is 'fp' (Frame Pointer), 'dwarf', 'lbr' (Last Branch Record) or 'no'
*/
private String cstack;
/** /**
* use simple class names instead of FQN * use simple class names instead of FQN
*/ */
@ -132,11 +148,6 @@ public class ProfilerCommand extends AnnotatedCommand {
*/ */
private boolean lib; private boolean lib;
/**
* include only kernel-mode events
*/
private boolean allkernel;
/** /**
* include only user-mode events * include only user-mode events
*/ */
@ -157,6 +168,21 @@ public class ProfilerCommand extends AnnotatedCommand {
*/ */
private List<String> excludes; private List<String> excludes;
/**
* automatically start profiling when the specified native function is executed.
*/
private String begin;
/**
* automatically stop profiling when the specified native function is executed.
*/
private String end;
/**
* time-to-safepoint profiling.
* An alias for --begin SafepointSynchronize::begin --end RuntimeService::record_safepoint_synchronized
*/
private boolean ttsp;
/** /**
* FlameGraph title * FlameGraph title
@ -280,6 +306,12 @@ public class ProfilerCommand extends AnnotatedCommand {
this.alloc = alloc; this.alloc = alloc;
} }
@Option(longName = "live", flag = true)
@Description("build allocation profile from live objects only")
public void setLive(boolean live) {
this.live = live;
}
@Option(longName = "lock") @Option(longName = "lock")
@Description("lock profiling threshold in nanoseconds") @Description("lock profiling threshold in nanoseconds")
public void setLock(String lock) { public void setLock(String lock) {
@ -292,6 +324,18 @@ public class ProfilerCommand extends AnnotatedCommand {
this.threads = threads; this.threads = threads;
} }
@Option(longName = "sched", flag = true)
@Description("group threads by scheduling policy")
public void setSched(boolean sched) {
this.sched = sched;
}
@Option(longName = "cstack")
@Description("how to traverse C stack: fp|dwarf|lbr|no")
public void setCstack(String cstack) {
this.cstack = cstack;
}
@Option(shortName = "s", flag = true) @Option(shortName = "s", flag = true)
@Description("use simple class names instead of FQN") @Description("use simple class names instead of FQN")
public void setSimple(boolean simple) { public void setSimple(boolean simple) {
@ -316,13 +360,7 @@ public class ProfilerCommand extends AnnotatedCommand {
this.lib = lib; this.lib = lib;
} }
@Option(longName = "allkernel", flag = true) @Option(longName = "all-user", flag = true)
@Description("include only kernel-mode events")
public void setAllkernel(boolean allkernel) {
this.allkernel = allkernel;
}
@Option(longName = "alluser", flag = true)
@Description("include only user-mode events") @Description("include only user-mode events")
public void setAlluser(boolean alluser) { public void setAlluser(boolean alluser) {
this.alluser = alluser; this.alluser = alluser;
@ -346,6 +384,25 @@ public class ProfilerCommand extends AnnotatedCommand {
this.excludes = excludes; this.excludes = excludes;
} }
@Option(longName = "begin")
@Description("automatically start profiling when the specified native function is executed")
public void setBegin(String begin) {
this.begin = begin;
}
@Option(longName = "end")
@Description("automatically stop profiling when the specified native function is executed")
public void setEnd(String end) {
this.end = end;
}
@Option(longName = "ttsp", flag = true)
@Description("time-to-safepoint profiling. "
+ "An alias for --begin SafepointSynchronize::begin --end RuntimeService::record_safepoint_synchronized")
public void setTtsp(boolean ttsp) {
this.ttsp = ttsp;
}
@Option(longName = "title") @Option(longName = "title")
@Description("FlameGraph title") @Description("FlameGraph title")
public void setTitle(String title) { public void setTitle(String title) {
@ -460,6 +517,9 @@ public class ProfilerCommand extends AnnotatedCommand {
if (this.alloc!= null) { if (this.alloc!= null) {
sb.append("alloc=").append(this.alloc).append(COMMA); sb.append("alloc=").append(this.alloc).append(COMMA);
} }
if (this.live) {
sb.append(this.live).append(COMMA);
}
if (this.lock!= null) { if (this.lock!= null) {
sb.append("lock=").append(this.lock).append(COMMA); sb.append("lock=").append(this.lock).append(COMMA);
} }
@ -478,6 +538,12 @@ public class ProfilerCommand extends AnnotatedCommand {
if (this.threads) { if (this.threads) {
sb.append("threads").append(COMMA); sb.append("threads").append(COMMA);
} }
if (this.sched) {
sb.append("sched").append(COMMA);
}
if (this.cstack != null) {
sb.append("cstack=").append(this.cstack).append(COMMA);
}
if (this.simple) { if (this.simple) {
sb.append("simple").append(COMMA); sb.append("simple").append(COMMA);
} }
@ -490,9 +556,6 @@ public class ProfilerCommand extends AnnotatedCommand {
if (this.lib) { if (this.lib) {
sb.append("lib").append(COMMA); sb.append("lib").append(COMMA);
} }
if (this.allkernel) {
sb.append("allkernel").append(COMMA);
}
if (this.alluser) { if (this.alluser) {
sb.append("alluser").append(COMMA); sb.append("alluser").append(COMMA);
} }
@ -506,6 +569,16 @@ public class ProfilerCommand extends AnnotatedCommand {
sb.append("exclude=").append(exclude).append(COMMA); sb.append("exclude=").append(exclude).append(COMMA);
} }
} }
if (this.ttsp) {
this.begin = "SafepointSynchronize::begin";
this.end = "RuntimeService::record_safepoint_synchronized";
}
if (this.begin != null) {
sb.append("begin=").append(this.begin).append(COMMA);
}
if (this.end != null) {
sb.append("end=").append(this.end).append(COMMA);
}
if (this.title != null) { if (this.title != null) {
sb.append("title=").append(this.title).append(COMMA); sb.append("title=").append(this.title).append(COMMA);

@ -281,3 +281,47 @@ profiler start -e alloc --alloc 2m
```bash ```bash
profiler start -f profile.jfr --chunksize 100m --chunktime 1h profiler start -f profile.jfr --chunksize 100m --chunktime 1h
``` ```
## 将线程按照调度策略分组
可以使用 `--sched` 标志选项将输出结果按照 Linux 线程调度策略分组,策略包括 BATCH/IDLE/OTHER。例如
```bash
profiler start --sched
```
火焰图的倒数第二行会标记不同的调度策略。
## 仅用未销毁对象构建内存分析结果
使用 `--live` 标志选项在内存分析结果中仅保留那些在分析过程结束时仍未被 JVM 回收的对象。该选项在排查 Java 堆内存泄露问题时比较有用。
```bash
profiler start --live
```
## 配置收集 C 栈帧的方法
使用 `--cstack MODE` 配置收集 native 帧的方法。候选模式有 fp (Frame Pointer), dwarf (DWARF unwind info), lbr (Last Branch Record, 从 Linux 4.1 在 Haswell 可用), and no (不收集 native 栈帧).
默认情况下C 栈帧会出现在 cpu、itimer、wall-clock、perf-events 模式中,而 Java 级别的 event 比如 alloc 和 lock 只收集 Java stack。
```bash
profiler --cstack fp
```
此命令将收集 native 栈帧的 Frame Pointer 信息。
## 当指定 native 函数执行时开始/停止 profiling
使用 `--begin function``--end function` 选项在指定 native 函数被执行时让 profiling 过程启动或终止。主要用途是分析特定的 JVM 阶段,比如 GC 和安全点。需要使用特定 JVM 实现中的 native 函数名,比如 HotSpot JVM 中的 `SafepointSynchronize::begin``SafepointSynchronize::end`
### Time-to-safepoint profiling
选项 `--ttsp` 实际上是 `--begin SafepointSynchronize::begin --end RuntimeService::record_safepoint_synchronized` 的一个别名。它是一种约束而不是独立的 event 类型。无论选择哪种 eventprofiler 都可以正常工作,但只有 VM 操作和 safepoint request 之间的事件会被记录下来。
```bash
profiler start --begin SafepointSynchronize::begin --end RuntimeService::record_safepoint_synchronized
profiler --ttsp
```

@ -281,3 +281,46 @@ When using JFR as output format, you can use `--chunksize` or `--chunktime` to c
```bash ```bash
profiler start -f profile.jfr --chunksize 100m --chunktime 1h profiler start -f profile.jfr --chunksize 100m --chunktime 1h
``` ```
## Group threads by scheduling policy
You can use `--sched` flag option to group threads in output by Linux-specific scheduling policy: BATCH/IDLE/OTHER, for example:
```bash
profiler start --sched
```
The second line from bottom in flamegraph represent the scheduling policy.
## Build allocation profile from live objects only
Use `--live` flag option to retain allocation samples with live objects only (object that have not been collected by the end of profiling session). Useful for finding Java heap memory leaks.
```bash
profiler start --live
```
## Config method of collecting C stack frames
Use `--cstack MODE` to config how to walk native frames (C stack). Possible modes are fp (Frame Pointer), dwarf (DWARF unwind info), lbr (Last Branch Record, available on Haswell since Linux 4.1), and no (do not collect C stack).
By default, C stack is shown in cpu, itimer, wall-clock and perf-events profiles. Java-level events like alloc and lock collect only Java stack.
```bash
profiler --cstack fp
```
The command above will collection Frame Pointer of C stacks.
## Begin or end profiling when FUNCTION is executed
Use `--begin function` and `--end function` to automatically start/stop profiling when the specified native function is executed. Its main purpose is to profile certain JVM phases like GC and Safepoint pauses. You should use native function name defined in a JVM implement, for example `SafepointSynchronize::begin` and `SafepointSynchronize::end` in HotSpot JVM.
### Time-to-safepoint profiling
The `--ttsp` option is an alias for `--begin SafepointSynchronize::begin --end RuntimeService::record_safepoint_synchronized`. It is not a separate event type, but rather a constraint. Whatever event type you choose (e.g. cpu or wall), the profiler will work as usual, except that only events between the safepoint request and the start of the VM operation will be recorded.
```bash
profiler start --begin SafepointSynchronize::begin --end RuntimeService::record_safepoint_synchronized
profiler --ttsp
```

Loading…
Cancel
Save