Java 很普通的代码执行很慢 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
burnbrid
V2EX    Java

Java 很普通的代码执行很慢

  •  
  •   burnbrid 2020-04-08 08:59:59 +08:00 8772 次点击
    这是一个创建于 2019 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大家好,我们生产系统上面现在有一个接口,这个接口里面的代码有的时候运行很慢,后来我把代码分成了好几段,每段代码前后都加了开始时间和结束时间。今天下午 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 大神给支点大招,谢谢各位大神。

    44 条回复    2020-04-09 14:53:05 +08:00
    ic2y
        1
    ic2y  
       2020-04-08 09:03:39 +08:00
    1.你的问题的格式 看起来 很乱,没有分行?

    2.如果是这种奇怪的问题,你得贴代码,还有平台、jdk 版本;只描述信息,没人看得懂
    redford42
        2
    redford42  
       2020-04-08 09:08:08 +08:00   7
    蹲点一下看走近科学结局
    cheng6563
        3
    cheng6563  
       2020-04-08 09:08:35 +08:00 via Android
    是不是开了 swap 内存不足了
    Aresxue
        4
    Aresxue  
       2020-04-08 09:11:47 +08:00
    jstack 看线程,打印什么的不靠谱,不一定是业务线程。我这就遇到过很多其他处理阻塞主程的操作, 比如日志输出(输出流重定向到 kafka )因为用的第三方库不够健壮一步发送 kafka 消息阻塞了业务线程。
    madizmChou
        5
    madizmChou  
       2020-04-08 09:12:28 +08:00
    多大的对象
    Aresxue
        6
    Aresxue  
       2020-04-08 09:13:09 +08:00
    条件允许直接上 arthas,把你整个函数切成片分析
    VoidChen
        7
    VoidChen  
       2020-04-08 09:13:20 +08:00
    我觉得是可能是资源占用问题,可以排查下服务器上部署了哪些组件,重点关注那些数据库或者搜索引擎,像 redis 或者 es 那种
    TMaize
        8
    TMaize  
       2020-04-08 09:13:34 +08:00 via Android
    代码里面有没有用生成随机数的相关函数
    micean
        9
    micean  
       2020-04-08 09:22:06 +08:00
    这种第一次慢,后面恢复正常的情况都是网络 IO 连接池假连接造成的
    sagaxu
        10
    sagaxu  
       2020-04-08 09:22:54 +08:00 via Android
    没有 gc 日志? fgc 叠加 swap 能卡几十秒,在内存 32G,剩余 20G 以上的情况下。
    arthas2234
        11
    arthas2234  
       2020-04-08 09:28:18 +08:00
    码字的时候能不能,分一下段落
    fzhyzamt
        12
    fzhyzamt  
       2020-04-08 09:34:24 +08:00
    你这什么条件都没,只能靠猜啊
    1. gc
    2. 插的桩有问题
    3. 那个对象是个代理,实际上是 IO
    4. 机器卡死
    5. 拿不到 CPU
    sampeng
        13
    sampeng  
       2020-04-08 09:52:32 +08:00 via iPhone   2
    监控都没,这不叫分析,这叫蒙
    nicevar
        14
    nicevar  
       2020-04-08 10:02:50 +08:00   2
    就你这个描述,James Gosling 来了也跟我在同一水平线上。。。
    问题不是出在语言上,可能出在环境或资源占用上
        15
    sherlockJuan  
       2020-04-08 10:07:49 +08:00
    手写 JDBCTemplate,压测试试,之前我们碰到过类似的问题,发现是有些类没管理好,访问量一上去,总是会重新创建对象,就变慢了
    nanguaboy
        16
    nanguaboy  
       2020-04-08 10:12:22 +08:00   1
    我猜一下,可能是随机数的原因
    thoreyunpeng
        17
    thoreyunpeng  
       2020-04-08 10:14:25 +08:00
    是不是 FGC 了 记录时间看 GCLog 吧
    shenlanAZ
        18
    shenlanAZ  
       2020-04-08 10:22:48 +08:00
    你这是在写日记
    MOETAN0
        19
    MOETAN0  
       2020-04-08 10:24:37 +08:00
    建议先做这 2 个事情:
    1,开启 jvm 的 GC 详细日志
    2,使用 nmon 等 linux 性能监控工具记录服务器运行性能指标
    haoz1w0w
        20
    haoz1w0w  
       2020-04-08 10:27:26 +08:00
    盲猜随机数
    rockyou12
        21
    rockyou12  
       2020-04-08 10:36:53 +08:00
    如果只在 linux 环境出问题,还真的很可能是系统的随机数生成的问题
    Jooooooooo
        22
    Jooooooooo  
       2020-04-08 10:57:13 +08:00
    重新提问吧
    purensong
        23
    purensong  
       2020-04-08 11:14:19 +08:00   1
    你这个提问没个分段,看不下去,不知道怎么这么多人评论的,我用心排版的帖就没几个人回复
    raymanr
        24
    raymanr  
       2020-04-08 11:19:42 +08:00
    我自己的一点个人经验, 我的电脑突然很卡的时候... 多半就是电脑散热底座的风扇接触不良没转了

    和代码不一定有关系
    itechify
        25
    itechify  
    PRO
       2020-04-08 11:43:46 +08:00 via Android
    感谢楼上大佬们,涨了新姿势,随机数生成会导致系统出问题
    crazyq
        26
    crazyq  
       2020-04-08 11:53:34 +08:00
    大佬们,为什么 Linux 将环境下随机数生成会导致系统慢呢。。
    cobola
        27
    cobola  
       2020-04-08 12:13:58 +08:00
    这种情况下 关机重启下就好了
    no1xsyzy
        28
    no1xsyzy  
       2020-04-08 12:16:07 +08:00
    @purensong #23 有几个原因:
    第一,这个问题过于开放,你可以看到就算很多人回,实质的帮助也是纯猜 而且随机数的问题被重复了 N 遍;
    第二,我稍微看了下你发的贴,哪怕存在排版的只有 /t/660127 这一个,但其中充斥着 off-topic fragments,比如 “不知道正则大佬们会不会”、“有兴趣的可以一起讨论”,段落组织结构上也不符合 why-how-what 的结构。
    图片还只插了缩略图。
    我那边帮你 reparagraphing 了一下,
    Darkside
        29
    Darkside  
       2020-04-08 12:17:53 +08:00   1
    @crazyq #26
    关键词:/dev/random 和 /dev/urandom 的区别
    purensong
        30
    purensong  
       2020-04-08 13:58:36 +08:00
    @no1xsyzy 好的,感谢回访。发帖确实不多,一般都习惯看别人的,段落组织我觉得没必要八股文吧。 表达清楚就可以了,off-topic 也只是片言,又不是官方发文需要字斟句酌。
    no1xsyzy
        31
    no1xsyzy  
       2020-04-08 14:07:45 +08:00
    @purensong #30 并不是八股,而是方便别人看,或者说这样自顶向下说更容易让地球人理解。
    off-topic 三两句还好,你这太多了,导致别人根本不知道你想表达什么,distraction 。
    wozhizui
        32
    wozhizui  
       2020-04-08 14:27:49 +08:00
    推荐可以往 jvm 调优的方向考虑,是不是系统的 class 很多。如果确定不是代码的问题,就从磁盘 io 、网络 io 方向考虑,排除后再考虑 jvm 调优,很有可能是 jvm 的内存管理的问题。
    毕竟如果是代码问题,能很容易看出来,复杂度大 O 啥的,很明显。
    lff0305
        33
    lff0305  
       2020-04-08 15:24:14 +08:00
    @crazyq linux java 默认调用的随机数生成器要从硬件操作(比如网络,磁盘读写)来构造. 在某些环境尤其是虚拟机,这个随机数生成的速度很慢,造成所有调用 java SecureRandom 的地方阻塞住(等待随机数).
    解决方法: 用-D 指定老式的种子 /数学运算来生成的伪随机数.
    lff0305
        34
    lff0305  
       2020-04-08 15:25:48 +08:00
    添加 printGC log 的参数重新试试 看看是不是出问题的时候 stop the world 了
    colincat
        35
    colincat  
       2020-04-08 15:36:35 +08:00
    arthas 拿这个工具去看看就知道了
    index90
        36
    index90  
       2020-04-08 15:55:31 +08:00
    估计是 stop the world 了
    fewok
        37
    fewok  
       2020-04-08 16:27:24 +08:00
    Thread.sleep(9000)
    挺简单代码,为啥需要执行 9 秒呢??
    yamasa
        38
    yamasa  
       2020-04-08 17:29:14 +08:00
    我一直觉得好的排版是学会提问的第一步。还是先 jstack jmap 和 gc 日志三步走起来看看吧。最好顺带把 jvm 在问题现场期间的 cpu 和 io 都 profile 一下看看
    HolmLoh
        39
    HolmLoh  
       2020-04-08 17:39:29 +08:00
    你有没有看过是否发生了 full gc
    Chinsung
        40
    Chinsung  
       2020-04-08 17:52:18 +08:00
    1.看一下 gc 日志,可能是当时发生了 full gc 。
    2.同一台宿主机上有没有其他服务在运行,可能是资源抢占导致的。
    z3jjlzt
        41
    z3jjlzt  
       2020-04-08 19:23:00 +08:00
    大概率 fjc 了
    RipL
        42
    RipL  
       2020-04-08 20:05:58 +08:00
    1.加 gc 日志,2. 接入 amp 工具,查看接口当时的 cpu 内存 jvm 等情况
    RipL
        43
    RipL  
       2020-04-08 20:06:42 +08:00
    @RipL apm 工具
    zhangjiayi1095
        44
    zhangjiayi1095  
       2020-04-09 14:53:05 +08:00
    arthas 看看这个方法的运行状态,到底是哪里慢
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     976 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 19:04 PVG 03:04 LAX 12:04 JFK 15:04
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86