如何定位 java 程序执行时间长的原因?
现在的问题是有一个定时程序执行一遍需要 1500 分钟,我需要减少执行时间,
而这个程序代码量也很大(多线程去遍历,然后统计数据 导出数据 删除数据),那么现在需要去定位什么原因导致的,有没有优化空间
有什么可以定位问题的工具? 我晓得的有 JProfiler 和 Arthas 但是具体用哪个功能,感到很迷茫,有的功能还对线上有比较大的影响
目前有一个 600G 的 kvrocks 集群(一个基于硬盘的类似 redis 的服务),然后每天需要遍历所有内容(开了大概 150 个线程去跑,因为读取 kvrocks 数据需要等待 io,于是开的线程多一些),为了实现业务需求主要有几个操作
cpu 10 核 20 线程 两个 (因为机器还在跑别的程序,基本已经跑满了 这个程序占用 3486% cpu)
内存 256G (这个程序占用 64G -Xmx64G)
[root@*** ~]# jstat -gcutil 39822
S0 S1 E O M CCS YGC YGCT FGC FGCT CGC CGCT GCT
0.00 94.84 29.51 51.33 98.33 93.37 28468 1151.061 0 0.000 16 4.057 1155.118
我有想过用 jstack 看看执行到哪里,不过这个程序是个大循环,一直都是那些代码再跑,看了貌似也没啥用
我现在只能去读代码,这种我感觉并不是对症下药,就是靠经验以及靠猜,这并不是一个好的解决问题的方法,所以在此求助各位大佬
1
aper 2023-08-29 10:10:57 +08:00
有没有可能是 kvrocks 慢导致的?
|
2
gy123 2023-08-29 10:13:23 +08:00
阿里 Arthas 的 trace 命令可以观测各方法执行时长,或者 idea 安装插件 jrebel 使用 Xrebel 也可以生成网页式的各方法节点时长,然后再具体分析~
|
3
gy123 2023-08-29 10:15:41 +08:00
cpu 占用 3486%,150 线程均摊大概每个线程占用 23%?感觉是不是楼上说的 kvrocks 慢,或者说是硬盘 io 导致的缓慢?看看有什么减少访问硬盘的优化空间
|
5
popvlovs 2023-08-29 10:22:13 +08:00
用 arthas 的 profiler 命令跑一个火焰图出来,比较直观
|
6
liprais 2023-08-29 10:24:03 +08:00 via iPhone
kvrocks 一次查询要多久
链接池用了么 网络带宽呢 |
7
chendy 2023-08-29 10:32:27 +08:00
简单粗暴的方法:加日志,记录一下每个操作的耗时,找到比较慢的然后再深入看
整个系统太复杂了,可能出现瓶颈的地方很多,只能慢慢查 |
8
opengps 2023-08-29 10:54:22 +08:00 1
建议观察几个点:
1 ,cpu 总消耗是不是满载,看余量是否有提升余地。 2 ,磁盘队列是不是满载,硬盘是文件读写类业务最经常触发的瓶颈点。 3 ,系统的线程数量是不是过大,上下文切换本身也是占用资源的,这个方面可以考虑压缩线程数量 4 ,看计算内容,是不是占用在额外的进程里,比如用 sql 计算和用程序计算,cpu 的消耗必然是在不同的进程位置里的,一般建议如果数据量不是特别大(读取耗时不是特别夸张的话),则让数据库回归原始的读写,程序拿来计算。 @gy123 这里应该不需要去考虑每个线程占用多少 cpu ,更应该考虑 20 个 vCPU 实际消耗 3486/20=174.2%的单核用量,这个数字 cpu 看起来已经不是普通的超频封顶数字了。我感觉 op 这个统计本身确实不太正常了 |
10
matepi 2023-08-29 10:54:34 +08:00
楼上说的 arthas 火焰图搞一把呗
不具备条件部署 arthas 条件的,也可以先用的简单的 jstack 打几个线程 dump 看看线程大都在跑什么,但若存在大有界循环之类的长时间不进 safepoint 情况,线程 dump 会不准 |
12
imokkkk 2023-08-29 10:55:59 +08:00
https://arthas.aliyun.com/doc/trace.html arthas trace 最外层方法 一层层往里面找 看哪些部分代码耗时最久 先定位问题 再看下有没有优化空间了
|
13
matepi 2023-08-29 10:59:45 +08:00
另外补一句,大有界循环可以用-XX:+UseCountedLoopSafepoints 参数之后拆解。
|
14
chenfang OP @opengps 3486/40=87.15 一共两个 cpu 一个 CPU 有 20 个逻辑核,也就是可用的是 40, 感谢,写文件应该比较多,貌似还是挂载写入,我具体看看这一块的内容
|
15
opengps 2023-08-29 11:02:57 +08:00
@chenfang 刚注意到是 2 颗。40 核心还有个要注意的问题,就是别把程序以及程序的类库编译成 x86 架构,因为 x86 架构最大只能用到 32 核
|
17
simonlu9 2023-08-29 11:17:18 +08:00
arthas trace,每个方法都可以跟踪使用多少时间
|
18
v2eb 2023-08-29 11:50:02 +08:00
日志记下/线程名/类名/方法名/方法耗时
|
19
akira 2023-08-29 14:06:28 +08:00
无脑猜 2 个地方, 硬盘没有上固态,或者统计的代码算法写的不好
|
20
stiangao 2023-08-29 14:38:23 +08:00
用 skywalking 挂 agent 去监控,可以看到各种耗时,arthas 适合线上排障一些小问题,这种监控的东西太多了不太能行。
用起来要学的东西有点多,需要可以扣联系 三八久寺灵五四二 8️⃣ |
21
szzadkk 2023-08-29 15:14:00 +08:00
用 arthas 的 profile start -e wall 生成火焰图,看函数的执行时间挨个分析就行
|
22
ihuotui 2023-08-29 22:01:13 +08:00
应该把任务做并发性能测试,1-10-100-100000 这样递增测试,看看是否效率提升,然后找性能瓶颈
|