Java 很普通的代码执行很慢

2020-04-08 08:59:59 +08:00
 burnbrid

大家好,我们生产系统上面现在有一个接口,这个接口里面的代码有的时候运行很慢,后来我把代码分成了好几段,每段代码前后都加了开始时间和结束时间。今天下午 2020/4/7 14:48:00 的时候,运维找我说又发现客户调了这个接口,我们 9 秒才返回结果。我去生产上把日志下载下来,发现在 2020/4/7 14:25:22 的时候,有一段很普通的 JAVA 代码(就是从一个对象上面调 get 方法,获取数据,不涉及 SQL 和多线程)确实运行了 9 秒。然后,我用同样的参数又调了一下那个接口,400 毫秒就返回了。邪门的是,并不是每次慢都是这段代码,有的时候是另外一段,有的时候又是另外一段代码。请问这种情况,你们是怎么分析问题并解决问题的?难道这种问题就解决不了吗?这种情况发生的不是太频繁,几乎 1 到 2 周会发生一次。我个人分析如下:1 、肯定不是 JAVA 代码的问题,因为这些代码都很简单,很普通。也不是数据库的问题。更不是网络的问题,因为就是那段普通 JAVA 代码运行了 9 秒。2 、既然不是 JAVA 代码和数据库、网络的问题,那么有可能是 JVM 的问题或者服务器的 CPU 或者 IO 的问题。现在我就是要找代码慢的那个时刻的 JVM 的概况和当时服务器 CPU 或者 IO 的概况。我想在代码中把 JVM 当时的堆栈内存情况打印出来。还有把当时服务器的 CPU 和 IO 概况也打印出来。不知道这样做是否可行?各位 JAVA 大神给支点大招,谢谢各位大神。

8089 次点击
所在节点    Java
44 条回复
rockyou12
2020-04-08 10:36:53 +08:00
如果只在 linux 环境出问题,还真的很可能是系统的随机数生成的问题
Jooooooooo
2020-04-08 10:57:13 +08:00
重新提问吧
purensong
2020-04-08 11:14:19 +08:00
你这个提问没个分段,看不下去,不知道怎么这么多人评论的,我用心排版的帖就没几个人回复
raymanr
2020-04-08 11:19:42 +08:00
我自己的一点个人经验, 我的电脑突然很卡的时候... 多半就是电脑散热底座的风扇接触不良没转了

和代码不一定有关系
oneisall8955
2020-04-08 11:43:46 +08:00
感谢楼上大佬们,涨了新姿势,随机数生成会导致系统出问题
crazyq
2020-04-08 11:53:34 +08:00
大佬们,为什么 Linux 将环境下随机数生成会导致系统慢呢。。
cobola
2020-04-08 12:13:58 +08:00
这种情况下 关机重启下就好了
no1xsyzy
2020-04-08 12:16:07 +08:00
@purensong #23 有几个原因:
第一,这个问题过于开放,你可以看到就算很多人回,实质的帮助也是纯猜 —— 而且随机数的问题被重复了 N 遍;
第二,我稍微看了下你发的贴,哪怕存在排版的只有 /t/660127 这一个,但其中充斥着 off-topic fragments,比如 “不知道正则大佬们会不会”、“有兴趣的可以一起讨论”,段落组织结构上也不符合 why-how-what 的结构。
图片还只插了缩略图。
我那边帮你 reparagraphing 了一下,
Darkside
2020-04-08 12:17:53 +08:00
@crazyq #26
关键词:/dev/random 和 /dev/urandom 的区别
purensong
2020-04-08 13:58:36 +08:00
@no1xsyzy 好的,感谢回访。发帖确实不多,一般都习惯看别人的,段落组织我觉得没必要八股文吧。 表达清楚就可以了,off-topic 也只是片言,又不是官方发文需要字斟句酌。
no1xsyzy
2020-04-08 14:07:45 +08:00
@purensong #30 并不是八股,而是方便别人看,或者说这样自顶向下说更容易让地球人理解。
off-topic 三两句还好,你这太多了,导致别人根本不知道你想表达什么,distraction 。
wozhizui
2020-04-08 14:27:49 +08:00
推荐可以往 jvm 调优的方向考虑,是不是系统的 class 很多。如果确定不是代码的问题,就从磁盘 io 、网络 io 方向考虑,排除后再考虑 jvm 调优,很有可能是 jvm 的内存管理的问题。
毕竟如果是代码问题,能很容易看出来,复杂度大 O 啥的,很明显。
lff0305
2020-04-08 15:24:14 +08:00
@crazyq linux java 默认调用的随机数生成器要从硬件操作(比如网络,磁盘读写)来构造. 在某些环境尤其是虚拟机,这个随机数生成的速度很慢,造成所有调用 java SecureRandom 的地方阻塞住(等待随机数).
解决方法: 用-D 指定老式的种子 /数学运算来生成的伪随机数.
lff0305
2020-04-08 15:25:48 +08:00
添加 printGC log 的参数重新试试 看看是不是出问题的时候 stop the world 了
colincat
2020-04-08 15:36:35 +08:00
arthas 拿这个工具去看看就知道了
index90
2020-04-08 15:55:31 +08:00
估计是 stop the world 了
fewok
2020-04-08 16:27:24 +08:00
Thread.sleep(9000)
挺简单代码,为啥需要执行 9 秒呢??
yamasa
2020-04-08 17:29:14 +08:00
我一直觉得好的排版是学会提问的第一步。还是先 jstack jmap 和 gc 日志三步走起来看看吧。最好顺带把 jvm 在问题现场期间的 cpu 和 io 都 profile 一下看看
HolmLoh
2020-04-08 17:39:29 +08:00
你有没有看过是否发生了 full gc
Chinsung
2020-04-08 17:52:18 +08:00
1.看一下 gc 日志,可能是当时发生了 full gc 。
2.同一台宿主机上有没有其他服务在运行,可能是资源抢占导致的。

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

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

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

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

© 2021 V2EX