V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
burnbrid
V2EX  ›  Java

Java 很普通的代码执行很慢

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

    大家好,我们生产系统上面现在有一个接口,这个接口里面的代码有的时候运行很慢,后来我把代码分成了好几段,每段代码前后都加了开始时间和结束时间。今天下午 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 来了也跟我在同一水平线上。。。
    问题不是出在语言上,可能出在环境或资源占用上
    sherlockJuan
        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
    我自己的一点个人经验, 我的电脑突然很卡的时候... 多半就是电脑散热底座的风扇接触不良没转了

    和代码不一定有关系
    oneisall8955
        25
    oneisall8955  
       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   ·   实用小工具   ·   5394 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 08:16 · PVG 16:16 · LAX 00:16 · JFK 03:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.