Java 程序执行时间太长优化的问题,求大佬解答

2023-08-29 10:06:39 +08:00
 chenfang

我现在的问题

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

现在的问题是有一个定时程序执行一遍需要 1500 分钟,我需要减少执行时间,

而这个程序代码量也很大(多线程去遍历,然后统计数据 导出数据 删除数据),那么现在需要去定位什么原因导致的,有没有优化空间

有什么可以定位问题的工具? 我晓得的有 JProfiler 和 Arthas 但是具体用哪个功能,感到很迷茫,有的功能还对线上有比较大的影响

程序逻辑

目前有一个 600G 的 kvrocks 集群(一个基于硬盘的类似 redis 的服务),然后每天需要遍历所有内容(开了大概 150 个线程去跑,因为读取 kvrocks 数据需要等待 io,于是开的线程多一些),为了实现业务需求主要有几个操作

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

机器配置

cpu 10 核 20 线程 两个 (因为机器还在跑别的程序,基本已经跑满了 这个程序占用 3486% cpu)

内存 256G (这个程序占用 64G -Xmx64G)

我能做的

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

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

2489 次点击
所在节点    程序员
22 条回复
aper
2023-08-29 10:10:57 +08:00
有没有可能是 kvrocks 慢导致的?
gy123
2023-08-29 10:13:23 +08:00
阿里 Arthas 的 trace 命令可以观测各方法执行时长,或者 idea 安装插件 jrebel 使用 Xrebel 也可以生成网页式的各方法节点时长,然后再具体分析~
gy123
2023-08-29 10:15:41 +08:00
cpu 占用 3486%,150 线程均摊大概每个线程占用 23%?感觉是不是楼上说的 kvrocks 慢,或者说是硬盘 io 导致的缓慢?看看有什么减少访问硬盘的优化空间
gy123
2023-08-29 10:16:24 +08:00
@gy123 还有这个占用,可以看下具体是什么线程占用的这么多,正不正常..
popvlovs
2023-08-29 10:22:13 +08:00
用 arthas 的 profiler 命令跑一个火焰图出来,比较直观
liprais
2023-08-29 10:24:03 +08:00
kvrocks 一次查询要多久
链接池用了么
网络带宽呢
chendy
2023-08-29 10:32:27 +08:00
简单粗暴的方法:加日志,记录一下每个操作的耗时,找到比较慢的然后再深入看
整个系统太复杂了,可能出现瓶颈的地方很多,只能慢慢查
opengps
2023-08-29 10:54:22 +08:00
建议观察几个点:
1 ,cpu 总消耗是不是满载,看余量是否有提升余地。
2 ,磁盘队列是不是满载,硬盘是文件读写类业务最经常触发的瓶颈点。
3 ,系统的线程数量是不是过大,上下文切换本身也是占用资源的,这个方面可以考虑压缩线程数量
4 ,看计算内容,是不是占用在额外的进程里,比如用 sql 计算和用程序计算,cpu 的消耗必然是在不同的进程位置里的,一般建议如果数据量不是特别大(读取耗时不是特别夸张的话),则让数据库回归原始的读写,程序拿来计算。

@gy123 这里应该不需要去考虑每个线程占用多少 cpu ,更应该考虑 20 个 vCPU 实际消耗 3486/20=174.2%的单核用量,这个数字 cpu 看起来已经不是普通的超频封顶数字了。我感觉 op 这个统计本身确实不太正常了
chenfang
2023-08-29 10:54:26 +08:00
@popvlovs 好的 我去研究研究 还没搞过火焰图
matepi
2023-08-29 10:54:34 +08:00
楼上说的 arthas 火焰图搞一把呗
不具备条件部署 arthas 条件的,也可以先用的简单的 jstack 打几个线程 dump 看看线程大都在跑什么,但若存在大有界循环之类的长时间不进 safepoint 情况,线程 dump 会不准
chenfang
2023-08-29 10:55:08 +08:00
@liprais 用的是 redisson 是有链接池的,不过你也提醒我了,我去看看链接池大小,谢谢
imokkkk
2023-08-29 10:55:59 +08:00
https://arthas.aliyun.com/doc/trace.html arthas trace 最外层方法 一层层往里面找 看哪些部分代码耗时最久 先定位问题 再看下有没有优化空间了
matepi
2023-08-29 10:59:45 +08:00
另外补一句,大有界循环可以用-XX:+UseCountedLoopSafepoints 参数之后拆解。
chenfang
2023-08-29 11:00:01 +08:00
@opengps 3486/40=87.15 一共两个 cpu 一个 CPU 有 20 个逻辑核,也就是可用的是 40, 感谢,写文件应该比较多,貌似还是挂载写入,我具体看看这一块的内容
opengps
2023-08-29 11:02:57 +08:00
@chenfang 刚注意到是 2 颗。40 核心还有个要注意的问题,就是别把程序以及程序的类库编译成 x86 架构,因为 x86 架构最大只能用到 32 核
gy123
2023-08-29 11:16:05 +08:00
@opengps 没错,总占用率是每个核心占用总和,应该先着手看下各核心相关数据
simonlu9
2023-08-29 11:17:18 +08:00
arthas trace,每个方法都可以跟踪使用多少时间
v2eb
2023-08-29 11:50:02 +08:00
日志记下/线程名/类名/方法名/方法耗时
akira
2023-08-29 14:06:28 +08:00
无脑猜 2 个地方, 硬盘没有上固态,或者统计的代码算法写的不好
stiangao
2023-08-29 14:38:23 +08:00
用 skywalking 挂 agent 去监控,可以看到各种耗时,arthas 适合线上排障一些小问题,这种监控的东西太多了不太能行。
用起来要学的东西有点多,需要可以扣联系 三八久寺灵五四二 8️⃣

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/969080

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX