我现在的问题

如何定位 java 程序执行时间长的原因?

现在的问题是有一个定时程序执行一遍需要 1500 分钟,我需要减少执行时间,
而这个程序代码量也很大(多线程去遍历,然后统计数据 导出数据 删除数据),那么现在需要去定位什么原因导致的,有没有优化空间
有什么可以定位问题的工具? 我晓得的有 JProfiler 和 Arthas 但是具体用哪个功能,感到很迷茫,有的功能还对线上有比较大的影响
程序逻辑
目前有一个 600G 的 kvrocks 集群(一个基于硬盘的类似 redis 的服务),然后每天需要遍历所有内容(开了大概 150 个线程去跑,因为读取 kvrocks 数据需要等待 io,于是开的线程多一些),为了实现业务需求主要有几个操作

删除过期的数据
导出一些数据到文件
插入 MQ 一些数据

机器配置
cpu 10 核 20 线程 两个 (因为机器还在跑别的程序,基本已经跑满了 这个程序占用 3486% cpu)
内存 256G (这个程序占用 64G -Xmx64G)
我能做的

查看 GC 情况,并没有 FGC,所以不是 FGC 导致的执行慢

[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 看看执行到哪里,不过这个程序是个大循环,一直都是那些代码再跑,看了貌似也没啥用

我现在只能去读代码,这种我感觉并不是对症下药,就是靠经验以及靠猜,这并不是一个好的解决问题的方法,所以在此求助各位大佬

有没有可能是 kvrocks 慢导致的?

阿里 Arthas 的 trace 命令可以观测各方法执行时长,或者 idea 安装插件 jrebel 使用 Xrebel 也可以生成网页式的各方法节点时长,然后再具体分析~

cpu 占用 3486%,150 线程均摊大概每个线程占用 23%?感觉是不是楼上说的 kvrocks 慢,或者说是硬盘 io 导致的缓慢?看看有什么减少访问硬盘的优化空间

还有这个占用,可以看下具体是什么线程占用的这么多,正不正常..

用 arthas 的 profiler 命令跑一个火焰图出来,比较直观

kvrocks 一次查询要多久链接池用了么网络带宽呢

简单粗暴的方法:加日志,记录一下每个操作的耗时,找到比较慢的然后再深入看整个系统太复杂了,可能出现瓶颈的地方很多,只能慢慢查

建议观察几个点:1 ,cpu 总消耗是不是满载,看余量是否有提升余地。2 ,磁盘队列是不是满载,硬盘是文件读写类业务最经常触发的瓶颈点。3 ,系统的线程数量是不是过大,上下文切换本身也是占用资源的,这个方面可以考虑压缩线程数量4 ,看计算内容,是不是占用在额外的进程里,比如用 sql 计算和用程序计算,cpu 的消耗必然是在不同的进程位置里的,一般建议如果数据量不是特别大(读取耗时不是特别夸张的话),则让数据库回归原始的读写,程序拿来计算。 这里应该不需要去考虑每个线程占用多少 cpu ,更应该考虑 20 个 vCPU 实际消耗 3486/20=174.2%的单核用量,这个数字 cpu 看起来已经不是普通的超频封顶数字了。我感觉 op 这个统计本身确实不太正常了

好的 我去研究研究 还没搞过火焰图

楼上说的 arthas 火焰图搞一把呗不具备条件部署 arthas 条件的,也可以先用的简单的 jstack 打几个线程 dump 看看线程大都在跑什么,但若存在大有界循环之类的长时间不进 safepoint 情况,线程 dump 会不准

用的是 redisson 是有链接池的,不过你也提醒我了,我去看看链接池大小,谢谢

arthas.aliyun.com/doc/trace.html arthas trace 最外层方法 一层层往里面找 看哪些部分代码耗时最久 先定位问题 再看下有没有优化空间了

另外补一句,大有界循环可以用-XX:+UseCountedLoopSafepoints 参数之后拆解。

3486/40=87.15 一共两个 cpu 一个 CPU 有 20 个逻辑核,也就是可用的是 40, 感谢,写文件应该比较多,貌似还是挂载写入,我具体看看这一块的内容

刚注意到是 2 颗。40 核心还有个要注意的问题,就是别把程序以及程序的类库编译成 x86 架构,因为 x86 架构最大只能用到 32 核

没错,总占用率是每个核心占用总和,应该先着手看下各核心相关数据

arthas trace,每个方法都可以跟踪使用多少时间

日志记下/线程名/类名/方法名/方法耗时

无脑猜 2 个地方, 硬盘没有上固态,或者统计的代码算法写的不好

用 skywalking 挂 agent 去监控,可以看到各种耗时,arthas 适合线上排障一些小问题,这种监控的东西太多了不太能行。用起来要学的东西有点多,需要可以扣联系 三八久寺灵五四二 8️⃣

用 arthas 的 profile start -e wall 生成火焰图,看函数的执行时间挨个分析就行

应该把任务做并发性能测试,1-10-100-100000 这样递增测试,看看是否效率提升,然后找性能瓶颈