Java 监控诊断利器 Arthas monitor/watch/trace 命令使用详解
目录
- 一、命令介绍
- 二、测试Demo
- 三、命令使用示例
- 3.1、monitor 命令
- 3.1.1、监控primeFactors方法调用情况(5秒一个周期,每过5秒将这5秒统计的信息输出)
- 3.1.2、监控primeFactors方法调用情况(5秒一个周期,每过5秒将这5秒统计的信息输出,一共输出两次)
- 3.1.3、计算条件表达式过滤统计结果(方法执行完毕之前)
- 3.1.4、计算条件表达式过滤统计结果(方法执行完毕之后)
- 3.2、watch 命令
- 3.2.1、观察函数调用返回时的参数、this 对象和返回值
- 3.2.2、同时观察函数调用前和函数返回后
- 3.2.3、条件表达式的例子
- 3.2.4、观察异常信息的例子
- 3.2.5、按照耗时进行过滤
- 3.2.6、观察当前对象中的属性
- 3.3、trace 命令
- 3.3.1、指定监控次数查看执行耗时和调用链路情况
- 3.3.2、包含 jdk 的函数查看执行耗时和调用链路情况
- 3.3.3、根据调用耗时过滤
- 3.3.4、trace 多个类或者多个函数
一、命令介绍
| 命令 | 说明 |
|---|---|
| monitor | 方法执行监控,可以对指定类的方法进行实时监控 (给定时间内调用次数、成功次数、失败次数、平均 RT等) |
| watch | 方法执行数据观测,可以观察到方法调用的入参、返参等 |
| trace | 方法内部调用路径,并输出方法路径上的每个节点上耗时 相当于本地链路追踪 |
这些命令,都通过字节码增强技术来实现的,会在指定类的方法中插入一些切面来实现数据统计和观测,因此在线上、预发使用时,请尽量明确需要观测的类、方法以及条件,诊断结束要执行 stop 或将增强过的类执行 reset 命令。
官网地址:https://arthas.gitee.io/doc
二、测试Demo
Arthas官网提供了一个测试Demo这里我稍微调整了一下,添加了一个内部内用于测试,官网提供了jar包和源码,我比较喜欢直接跑源码,源码在github我这里把代码粘贴过来避免访问不了,将测试Demo运行起来使用arthas-boot.jar连接上准备开始命令使用。
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;public class MathGame {private static Random random = new Random();private int illegalArgumentCount = 0;public static void main(String[] args) throws InterruptedException {MathGame game = new MathGame();while (true) {game.run();TimeUnit.SECONDS.sleep(1);}}public void run() throws InterruptedException {try {int number = random.nextInt()/10000;List<Integer> primeFactors = primeFactors(number);print(number, primeFactors);} catch (Exception e) {System.out.println(String.format("illegalArgumentCount:%3d, ", illegalArgumentCount) + e.getMessage());}}public static void print(int number, List<Integer> primeFactors) {StringBuffer sb = new StringBuffer(number + "=");for (int factor : primeFactors) {sb.append(factor).append('*');}if (sb.charAt(sb.length() - 1) == '*') {sb.deleteCharAt(sb.length() - 1);}System.out.println(sb);}public List<Integer> primeFactors(int number) {System.out.println("当前时间戳:"+new DateTimeUtils().getNow());if (number < 2) {illegalArgumentCount++;throw new IllegalArgumentException("number is: " + number + ", need >= 2");}List<Integer> result = new ArrayList<Integer>();int i = 2;while (i <= number) {if (number % i == 0) {result.add(i);number = number / i;i = 2;} else {i++;}}return result;}class DateTimeUtils {public String getNow() {return String.valueOf(System.currentTimeMillis());}}
}
三、命令使用示例
3.1、monitor 命令
monitor方法执行监控是一个很简单好用的线上方法调用响应情况观察工具,可以对指定类的方法进行实时监控,当线上某个业务响应慢时可以使用monitor对这个方法进行监控查看平均耗时,但是monitor没有监控整个链路每一步的处理时间的能力有需要可以使用trace命令。
- 监控的维度说明
| 监控项 | 说明 |
|---|---|
| timestamp | 时间戳 |
| class | Java 类 |
| method | 方法(构造方法、普通方法) |
| total | 调用次数 |
| success | 成功次数 |
| fail | 失败次数 |
| rt | 平均 RT |
| fail-rate | 失败率 |
- 参数说明
方法拥有一个命名参数 [c:],意思是统计周期(cycle of output),拥有一个整型的参数值
| 参数名称 | 参数说明 |
|---|---|
| class-pattern | 类名表达式匹配(支持通配符*) |
| method-pattern | 方法名表达式匹配(支持通配符*) |
| condition-express | 条件表达式 |
| [E] | 开启正则表达式匹配,默认为通配符匹配 |
| [c:] | 统计周期,默认值为 120 秒 |
| [b] | 在方法调用之前计算 condition-express |
| [m ] | 指定 Class 最大匹配数量,默认值为 50。长格式为[maxMatch ] 因为类名支持通配符所以可能会匹配多个类,可以用-m限制 |
| [n:]] | 指定统计周期次数 |
3.1.1、监控primeFactors方法调用情况(5秒一个周期,每过5秒将这5秒统计的信息输出)
我这里收集了3次,使用Ctrl+C退出收集
[arthas@9336]$ monitor -c 5 demo.MathGame primeFactors
Press Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 23 ms, listenerId: 1 timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2024-01-04 21:12:00 demo.MathGame primeFactors 5 1 4 0.25 80.00%timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2024-01-04 21:12:05 demo.MathGame primeFactors 5 1 4 0.03 80.00%timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2024-01-04 21:12:10 demo.MathGame primeFactors 5 4 1 0.66 20.00%
3.1.2、监控primeFactors方法调用情况(5秒一个周期,每过5秒将这5秒统计的信息输出,一共输出两次)
[arthas@9336]$ monitor -c 5 -n 2 demo.MathGame primeFactors
Press Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 23 ms, listenerId: 2 timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2024-01-04 21:28:50 demo.MathGame primeFactors 5 4 1 0.73 20.00%timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2024-01-04 21:28:55 demo.MathGame primeFactors 5 5 0 0.11 0.00%Command execution times exceed limit: 2, so command will exit. You can set it with -n option.
3.1.3、计算条件表达式过滤统计结果(方法执行完毕之前)
这个方法执行完毕之前的意思是,会先判断入参是否小于等于2,如果小于等于2才记录统计,不然不记录,因为入参小于2会抛出异常,所以这里很大概率都是会失败的,默认是在方法执行完毕之后判断表达式。
[arthas@9336]$ monitor -c 5 -n 3 -b demo.MathGame primeFactors "params[0] <= 2"
Press Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 23 ms, listenerId: 3 timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2024-01-04 21:39:03 demo.MathGame primeFactors 2 0 2 0.08 100.00%timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2024-01-04 21:39:08 demo.MathGame primeFactors 3 0 3 0.02 100.00%timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2024-01-04 21:39:13 demo.MathGame primeFactors 2 0 2 0.03 100.00%Command execution times exceed limit: 3, so command will exit. You can set it with -n option.
3.1.4、计算条件表达式过滤统计结果(方法执行完毕之后)
这个好像没有效果,按照我的理解应该是primeFactors方法执行完成后进行条件表达式判断,只取出入参小于等于2的记录做统计,但是这里还是取出了全部数据
[arthas@9336]$ monitor -c 5 -n 3 demo.MathGame primeFactors "params[0] <= 2"
Press Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 23 ms, listenerId: 4 timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2024-01-04 21:45:51 demo.MathGame primeFactors 5 2 3 0.67 60.00%timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2024-01-04 21:45:56 demo.MathGame primeFactors 5 0 5 0.24 100.00%timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2024-01-04 21:46:01 demo.MathGame primeFactors 5 4 1 0.31 20.00%Command execution times exceed limit: 3, so command will exit. You can set it with -n option.
3.2、watch 命令
watch让你能方便的观察到指定函数的调用情况。能观察到的范围为:返回值、抛出异常、入参,通过编写 OGNL 表达式进行对应变量的查看。
- 参数说明
watch 的参数比较多,主要是因为它能在 4 个不同的场景观察对象
| 参数名称 | 参数说明 |
|---|---|
| class-pattern | 类名表达式匹配 |
| method-pattern | 函数名表达式匹配 |
| express | 观察表达式,默认值:{params, target, returnObj} |
| condition-express | 条件表达式 |
| [b] | 在函数调用之前观察 |
| [e] | 在函数异常之后观察 |
| [s] | 在函数返回之后观察 |
| [f] | 在函数结束之后(正常返回和异常返回)观察 |
| [E] | 开启正则表达式匹配,默认为通配符匹配 |
| [x:] | 指定输出结果的属性遍历深度,默认为 1,最大值是 4 |
| [m ] | 指定 Class 最大匹配数量,默认值为 50。长格式为[maxMatch ] |
| [n:] | 命令执行次数 |
| #cost | 方法执行耗时 |
这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写"{params,returnObj}",只要是一个合法的 ognl 表达式,都能被正常支持。
- 特别说明
- watch 命令定义了 4 个观察事件点,即 -b 函数调用前,-e 函数异常后,-s 函数返回后,-f 函数结束后
- 4 个观察事件点 -b、-e、-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出
这里要注意函数入参和函数出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表函数入参外,其余事件都代表函数出参 - 当使用 -b 时,由于观察事件点是在函数调用前,此时返回值或异常均不存在
- 在 watch 命令的结果里,会打印出location信息。location有三种可能值:AtEnter,AtExit,AtExceptionExit。对应函数入口,函数正常 return,函数抛出异常。
3.2.1、观察函数调用返回时的参数、this 对象和返回值
[arthas@3764]$ watch demo.MathGame primeFactors -x 2 -n 1
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 20 ms, listenerId: 2
method=demo.MathGame.primeFactors location=AtExit
ts=2024-01-08 20:58:31; [cost=1.901ms] result=@ArrayList[ @Object[][ @Integer[1], ], @MathGame[ random=@Random[java.util.Random@28c97a5], illegalArgumentCount=@Integer[53], ], @ArrayList[ @Integer[2], @Integer[95539], ],
]
Command execution times exceed limit: 1, so command will exit. You can set it with -n option.
- 观察表达式,默认值是
{params, target, returnObj} -x表示遍历深度,可以调整来打印具体的参数和结果内容,默认值是 1。-x最大值是 4,防止展开结果占用太多内存。用户可以在ognl表达式里指定更具体的 field。-n 1代表执行一次就退出,-n这个参数在每个Arthas命令中基本都有只是没有写出来而已
3.2.2、同时观察函数调用前和函数返回后
[arthas@3764]$ watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 18 ms, listenerId: 10
method=demo.MathGame.primeFactors location=AtEnter
ts=2024-01-08 21:09:35; [cost=0.0407ms] result=@ArrayList[ @Object[][ @Integer[132070], ], @MathGame[ random=@Random[java.util.Random@28c97a5], illegalArgumentCount=@Integer[402], ], null,
]
method=demo.MathGame.primeFactors location=AtExit
ts=2024-01-08 21:09:35; [cost=2151892.1309ms] result=@ArrayList[ @Object[][ @Integer[1], ], @MathGame[ random=@Random[java.util.Random@28c97a5], illegalArgumentCount=@Integer[402], ], @ArrayList[ @Integer[2], @Integer[5], @Integer[47], @Integer[281], ],
]
Command execution times exceed limit: 2, so command will exit. You can set it with -n option.
-
参数里-n 2,表示只执行两次
-
这里输出结果中,第一次输出的是函数调用前的观察表达式的结果,第二次输出的是函数返回后的表达式的结果
-
结果的输出顺序和事件发生的先后顺序一致,和命令中
-s-b的顺序无关
3.2.3、条件表达式的例子
[arthas@3764]$ watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0" -n 2
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 16 ms, listenerId: 14
method=demo.MathGame.primeFactors location=AtExceptionExit ts=2024-01-08 21:18:02; [cost=0.3214ms] result=@ArrayList[ @Integer[-181424], @MathGame[demo.MathGame@6659c656],
]
method=demo.MathGame.primeFactors location=AtExceptionExit
ts=2024-01-08 21:18:03; [cost=0.0878ms] result=@ArrayList[ @Integer[-202266], @MathGame[demo.MathGame@6659c656],
]
Command execution times exceed limit: 2, so command will exit. You can set it with -n option.
params[0]<0当第一个参数小于0是响应
3.2.4、观察异常信息的例子
[arthas@3764]$ watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2 -n 1
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 17 ms, listenerId: 17
method=demo.MathGame.primeFactors location=AtExceptionExit
ts=2024-01-08 21:24:17; [cost=0.3626ms] result=@ArrayList[ @Integer[-212025], java.lang.IllegalArgumentException: number is: -212025, need >= 2 at demo.MathGame.primeFactors(MathGame.java:47) at demo.MathGame.run(MathGame.java:24) at demo.MathGame.main(MathGame.java:16)
,
]
Command execution times exceed limit: 1, so command will exit. You can set it with -n option.
-e表示抛出异常时才触发- express 观察表达式中,表示异常信息的变量是throwExp
3.2.5、按照耗时进行过滤
[arthas@3764]$ watch demo.MathGame primeFactors '{params, returnObj}' '#cost>0.5' -x 2 -n 1
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 19 ms, listenerId: 22
method=demo.MathGame.primeFactors location=AtExit
ts=2024-01-08 21:30:26; [cost=1.1834ms] result=@ArrayList[ @Object[][ @Integer[1], ], @ArrayList[ @Integer[2], @Integer[63347], ],
]
Command execution times exceed limit: 1, so command will exit. You can set it with -n option.
#cost>0.5(单位是ms)表示只有当耗时大于 0.5ms 时才会输出,过滤掉执行时间小于 0.5ms 的调用
3.2.6、观察当前对象中的属性
[arthas@3764]$ watch demo.MathGame primeFactors '{params,target.illegalArgumentCount}' -x 2 -n 1
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 19 ms, listenerId: 26
method=demo.MathGame.primeFactors location=AtExit
ts=2024-01-08 21:34:00; [cost=0.2875ms] result=@ArrayList[ @Object[][ @Integer[1], ], @Integer[1149],
]
Command execution times exceed limit: 1, so command will exit. You can set it with -n option.
- 可以使用
target.field_name访问当前对象的某个属性,target相当于当前对象
3.3、trace 命令
trace 命令能监控方法内部调用路径,并输出方法路径上的每个节点上耗时,方便的帮助定位和发现因 RT 高而导致的性能问题缺陷,trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。
- 参数说明
| 参数名称 | 参数说明 |
|---|---|
| class-pattern | 类名表达式匹配(支持通配符*) |
| method-pattern | 方法名表达式匹配(支持通配符*) |
| condition-express | 条件表达式 |
| [E] | 开启正则表达式匹配,默认为通配符匹配 |
| [n:] | 命令执行次数 |
| #cost | 方法执行耗时 |
| [m ] | 指定 Class 最大匹配数量,默认值为 50。长格式为[maxMatch ] 因为类名支持通配符所以可能会匹配多个类,可以用-m限制 |
| –skipJDKMethod | 是否包含 jdk 的函数,默认false,不显示jdk函数调用 |
这里重点要说明的是条件表达式,条件表达式的构成主要由 ognl 表达式组成,所以你可以这样写"params[0]<0",只要是一个合法的 ognl 表达式,都能被正常支持。
很多时候我们只想看到某个方法的 RT 大于某个时间之后的 trace 结果,现在 Arthas 可以按照方法执行的耗时来进行过滤了,例如trace *StringUtils isBlank '#cost>100’表示当执行时间超过 100ms 的时候,才会输出 trace 的结果。
- 注意事项
trace监控后看到的结果时间可能不准确,总耗时看到的是1000ms,但是打印的链路耗时加起来只有500ms,这是因为有些类和函数没有被trace到,或者非函数调用的指令消耗。比如i++, getfield等指令。又或者是在代码执行过程中,JVM 可能出现停顿,比如 GC,进入同步块等。
3.3.1、指定监控次数查看执行耗时和调用链路情况
监控 demo.MathGame 类中 run() 方法执行耗时和调用链路情况(可以通过-n 指定监控次数,不指定会一直监控)
[arthas@3432]$ trace demo.MathGame run -n 3
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 16 ms, listenerId: 3
`---ts=2024-01-08 16:10:05;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[0.4212ms] demo.MathGame:run() +---[18.71% 0.0788ms ] demo.MathGame:primeFactors() #24 `---[48.98% 0.2063ms ] demo.MathGame:print() #25 `---ts=2024-01-08 16:10:06;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[0.518ms] demo.MathGame:run() `---[25.14% 0.1302ms ] demo.MathGame:primeFactors() #24 [throws Exception] `---ts=2024-01-08 16:10:07;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[0.3005ms] demo.MathGame:run() `---[28.15% 0.0846ms ] demo.MathGame:primeFactors() #24 [throws Exception]Command execution times exceed limit: 3, so command will exit. You can set it with -n option.
3.3.2、包含 jdk 的函数查看执行耗时和调用链路情况
监控 demo.MathGame 类中 run() 方法执行耗时和调用链路情况,包含 jdk 的函数
[arthas@5848]$ trace --skipJDKMethod false demo.MathGame run
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 42 ms, listenerId: 7
`---ts=2024-01-08 16:33:53;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[0.8148ms] demo.MathGame:run() +---[8.09% 0.0659ms ] java.util.Random:nextInt() #24 +---[21.94% 0.1788ms ] demo.MathGame:primeFactors() #25 `---[33.21% 0.2706ms ] demo.MathGame:print() #26 `---ts=2024-01-08 16:33:54;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[0.2696ms] demo.MathGame:run() +---[4.15% 0.0112ms ] java.util.Random:nextInt() #24 +---[32.31% 0.0871ms ] demo.MathGame:primeFactors() #25 `---[34.94% 0.0942ms ] demo.MathGame:print() #26 `---ts=2024-01-08 16:33:55;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[0.5625ms] demo.MathGame:run() +---[1.37% 0.0077ms ] java.util.Random:nextInt() #24 +---[30.31% 0.1705ms ] demo.MathGame:primeFactors() #25 [throws Exception] +---[1.96% 0.011ms ] java.lang.StringBuilder:<init>() #29 +---[21.40% 0.1204ms ] java.lang.String:format() #29 +---[2.24% min=0.0046ms,max=0.008ms,total=0.0126ms,count=2] java.lang.StringBuilder:append() #29 +---[1.10% 0.0062ms ] java.lang.Exception:getMessage() #29 +---[1.08% 0.0061ms ] java.lang.StringBuilder:toString() #29 `---[12.73% 0.0716ms ] java.io.PrintStream:println() #29
3.3.3、根据调用耗时过滤
监控 demo.MathGame 类中 run() 方法执行耗时和调用链路情况,据调用耗时过滤
[arthas@5848]$ trace demo.MathGame run '#cost > 0.5'
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 14 ms, listenerId: 10
`---ts=2024-01-08 16:40:23;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[0.9167ms] demo.MathGame:run() +---[20.29% 0.186ms ] demo.MathGame:primeFactors() #25 `---[37.11% 0.3402ms ] demo.MathGame:print() #26`---ts=2024-01-08 16:40:27;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[1.6932ms] demo.MathGame:run() `---[30.12% 0.51ms ] demo.MathGame:primeFactors() #25 [throws Exception]`---ts=2024-01-08 16:40:52;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[0.5762ms] demo.MathGame:run() +---[77.91% 0.4489ms ] demo.MathGame:primeFactors() #25 `---[14.58% 0.084ms ] demo.MathGame:print() #26
3.3.4、trace 多个类或者多个函数
在MathGame代码中我们还调用了一个内部类DateTimeUtils的getNow()方法(外部类也是一样的写出demo.DateTimeUtils即可),在链路中并没有输出,因为trace 命令只会 trace 匹配到的函数里的子调用,并不会向下 trace 多层。因为 trace 是代价比较昂贵的,多层 trace 可能会导致最终要 trace 的类和函数非常多。
可以用正则表匹配路径上的多个类和函数,一定程度上达到多层 trace 的效果。
[arthas@3464]$ trace -E demo.MathGame|demo.MathGame.DateTimeUtils run|getNow
Press Q or Ctrl+C to abort.
Affect(class count: 2 , method count: 2) cost in 27 ms, listenerId: 8
`---ts=2024-01-08 17:07:15;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[1.5505ms] demo.MathGame:run() `---[63.54% 0.9852ms ] demo.MathGame:primeFactors() #24 [throws Exception] `---[24.59% 0.2423ms ] demo.MathGame$DateTimeUtils:getNow() `---ts=2024-01-08 17:07:16;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[0.341801ms] demo.MathGame:run() `---[46.96% 0.1605ms ] demo.MathGame:primeFactors() #24 [throws Exception] `---[20.12% 0.0323ms ] demo.MathGame$DateTimeUtils:getNow() `---ts=2024-01-08 17:07:17;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[0.870299ms] demo.MathGame:run() +---[57.59% 0.5012ms ] demo.MathGame:primeFactors() #24 | `---[3.91% 0.0196ms ] demo.MathGame$DateTimeUtils:getNow() `---[29.53% 0.257ms ] demo.MathGame:print() #25
相关文章:
Java 监控诊断利器 Arthas monitor/watch/trace 命令使用详解
目录 一、命令介绍二、测试Demo三、命令使用示例3.1、monitor 命令3.1.1、监控primeFactors方法调用情况(5秒一个周期,每过5秒将这5秒统计的信息输出)3.1.2、监控primeFactors方法调用情况(5秒一个周期,每过5秒将这5秒…...
论文阅读:基于MCMC的能量模型最大似然学习剖析
On the Anatomy of MCMC-Based Maximum Likelihood Learning of Energy-Based Models 相关代码:点击 本文只介绍关于MCMC训练的部分,由此可知,MCMC常常被用于训练EBM。最后一张图源于Implicit Generation and Modeling with Energy-Based Mod…...
【Verilog】期末复习——设计一个带异步复位端且高电平有效的32分频电路
系列文章 数值(整数,实数,字符串)与数据类型(wire、reg、mem、parameter) 运算符 数据流建模 行为级建模 结构化建模 组合电路的设计和时序电路的设计 有限状态机的定义和分类 期末复习——数字逻辑电路分…...
基于springboot的java读取文档内容(超简单)
读取一个word文档里面的内容,并取出来。 代码: SneakyThrowsGetMapping(value "/readWordDoc")ApiOperationSupport(order 1)ApiOperation(value "文档读取 ", notes "文档读取 ")public R ReadWordDoc () {System.o…...
K8S亲和性,反亲和性,及污点
nodeName:硬匹配,不走调度策略 nodeSelector:根据节点的标签选择,会走调度的算法 只要是走调度算法,在不满足预算策略的情况下,所有pod都是pending node节点的亲和性: 硬策略:必…...
2024年,AI、Web3、区块链、元宇宙:有没有“相互成就“的可能性?
加密圈最近有点冷清,曾经是科技界的宠儿,去年中旬开始一直在被SEC的诉讼困扰着,而且正处冷清的熊市,被迫居于 AI 后面的次要地位。 曾在 Web3 领域活跃并具有影响力的企业家 Jeremiah Owyang 住在旧金山,目前也深入研…...
Mac电脑好用的修图软件:Affinity Photo 2中文 for Mac
Affinity Photo 2提供了广泛的图像编辑和调整工具,使用户能够对照片进行精确的编辑和改进。它支持图像裁剪、旋转、缩放、变形等操作,以及曝光、色彩、对比度、饱和度等调整。 非破坏性编辑:软件采用非破坏性编辑方式,即对原始图…...
数据结构之Radix和Trie
数据结构可视化演示链接,也就是视频中的网址 Radix树:压缩后的Trie树 Radix叫做基数树(压缩树),就是有相同前缀的字符串,其前缀可以作为一个公共的父节点。同时在具体存储上,Radix树的处理是以…...
ctrl+c与kill -2的区别
单进程场景 在单进程的情况下,ctrlc和kill -2是一模一样的,都是向指定的进程发送SIGINT信号. 如果进程中注册了捕捉SIGINT信号的处理函数,那么这个信号会被进程处理,例如: void processB() {// Set signal handler …...
每日算法打卡:分巧克力 day 9
文章目录 原题链接题目描述输入格式输出格式数据范围输入样例:输出样例: 题目分析示例代码 原题链接 1227. 分巧克力 题目难度:简单 题目来源:第八届蓝桥杯省赛C A/B组,第八届蓝桥杯省赛Java A/B/C组 题目描述 儿童节那天有 …...
Golang switch 语句
简介 switch 语句提供了一种简洁的方式来执行多路分支选择 基本使用 基本语法如下: switch expression { case value1:// 当 expression 的值等于 value1 时执行 case value2:// 当 expression 的值等于 value2 switch 的每个分支自动提供了隐式的 break&#x…...
可碧教你C++——位图
本章节是哈希的延申 可碧教你C——哈希http://t.csdnimg.cn/3R8TU 一文详解C——哈希 位图 位图是基于哈希表的原理产生的一种新的container——bitset 基于哈希映射的原理,我们在查找的时候,可以直接去定址到元素的具体位置,然后直接访问该…...
2024年虚拟DOM技术将何去何从?
从诞生之初谈起,从命令式到声明式,Web开发的演变之路 Web开发的起源与jQuery的统治 在Web开发的早期阶段,操作DOM元素主要依赖命令式编程。当时,jQuery因其易用性而广受欢迎。使用jQuery,开发者通过具体的命令操作DOM&…...
基于51单片机的恒温淋浴器控制电路设计
标题:基于51单片机的智能恒温淋浴器控制系统设计与实现 摘要: 本论文主要探讨了一种基于STC89C51单片机为核心控制器的恒温淋浴器控制系统的详细设计与实现。系统通过集成温度传感器实时监测水温,结合PID算法精确控制加热元件工作状态&#…...
【redis】redis的bind配置
在配置文件redis.conf中,默认的bind 接口是127.0.0.1,也就是本地回环地址。这样的话,访问redis服务只能通过本机的客户端连接,而无法通过远程连接, 这样可以避免将redis服务暴露于危险的网络环境中,防止一些…...
C++ 继承
目录 一、继承的概念及定义 1、继承的概念 2、继承定义 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派生类的默认成员函数 五、继承与友元 六、继承与静态成员 七、复杂的菱形继承及菱形虚拟继承 1、菱形继承 2、虚拟继承 3、例题 八、继承的总结和反思…...
了解ASP.NET Core 中的文件提供程序
写在前面 ASP.NET Core 通过文件提供程序来抽象化文件系统访问。分为物理文件提供程序(PhysicalFileProvider)和清单嵌入的文件提供程序(ManifestEmbeddedFileProvider)还有复合文件提供程序(CompositeFileProvider );其中PhysicalFileProvider 提供对物理文件系统…...
竞赛保研 基于深度学习的人脸性别年龄识别 - 图像识别 opencv
文章目录 0 前言1 课题描述2 实现效果3 算法实现原理3.1 数据集3.2 深度学习识别算法3.3 特征提取主干网络3.4 总体实现流程 4 具体实现4.1 预训练数据格式4.2 部分实现代码 5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 毕业设计…...
JavaScript音视频,JavaScript简单获取电脑摄像头画面并播放
前言 本章实现JavaScript简单获取电脑摄像头画面并播放的功能 兼容性(不支持Node.js) 需要注意的是,由于涉及到用户的隐私和安全,获取用户媒体设备需要用户的明确同意,并且可能需要在用户的浏览器中启用相关的权限。在某些浏览器中,可能需要用户手动开启摄像头权限。 …...
《JVM由浅入深学习【五】 2024-01-08》JVM由简入深学习提升分享
目录 JVM何时会发生堆内存溢出?1. 堆内存溢出的定义2. 内存泄漏的原因3. 堆内存溢出的常见场景4. JVM参数调优5. 实际案例分析 JVM如何判断对象可以回收1.可达性分析的基本思路2.实际案例3.可以被回收的对象4.拓展, 谈谈 Java 中不同的引用类型? 结语感…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...
