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

可复现的 Java 进程卡死,如何排查问题

  •  
  •   nonoyang · 8 天前 · 1640 次点击

    场景:有一个单独的服务,用于测试一个大的定时任务(包含大量读写操作),定时任务运行大概 30 分钟后,会出现卡死情况。Java 进程还存在但处于暂停状态。日志停止输出,且没有任何报错。

    进程信息: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 8831 **** 20 0 9781344 2.491g 14912 t 0.0 8.0 23:50.15 java

    gc 部分日志: 2021-11-24T09:43:51.293+0800: 58343.178: [GC (Allocation Failure) [PSYoungGen: 1045888K->416K(1047552K)] 1379025K->333593K(2096128K), 0.0061813 secs] [Times: user=0.02 sys=0.01, real=0.01 secs] 2021-11-24T09:44:37.862+0800: 58389.746: [GC (Allocation Failure) [PSYoungGen: 1046944K->288K(1047552K)] 1380121K->333473K(2096128K), 0.0063377 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 2021-11-24T09:45:23.641+0800: 58435.526: [GC (Allocation Failure) [PSYoungGen: 1046816K->387K(1047552K)] 1380001K->333597K(2096128K), 0.0063043 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]

    卡死后,jmap,jstack 相关指令都无法再执行了。 数据库用的是 oracle 12c,查看还是正常的,所以应该不是数据库的问题。 请问大佬们,现在有啥排查问题的手段吗?

    18 条回复    2021-11-25 10:17:29 +08:00
    darrh00
        1
    darrh00  
       8 天前
    什么环境?
    如果是 Linux 的话可以试试 kill -QUIT pid
    yanweichen0720
        2
    yanweichen0720  
       8 天前   ❤️ 1
    启动的时候加上远程监控的参数,然后用 jmc 实时看下具体哪些类炸了
    nonoyang
        3
    nonoyang  
    OP
       8 天前
    @darrh00 是 linux
    huntagain2008
        4
    huntagain2008  
       8 天前
    建议追加附言用 markdown 的代码块把进程信息和日志显示的漂亮点。
    whx
        5
    whx  
       8 天前 via iPhone
    看起来是内存满了不够用导致的,可以把-Xmx 调大一点试下。
    cheng6563
        6
    cheng6563  
       8 天前   ❤️ 1
    -XX:+ExitOnOutOfMemoryError -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=12345.hprof
    加这仨参数,使其发生内存问题时直接退出并留下 dump ,然后分析 dump 就行了。
    java 发生 OOM 错误时很容易失控,不退出也往往不能正常工作,还不如直接退掉让守护进程重新拉起来了事。
    zxyroy
        7
    zxyroy  
       8 天前
    可以排查下是不是有什么 stream 忘记 close 了
    nonoyang
        8
    nonoyang  
    OP
       8 天前
    @zxyroy 这个应该是不存在的。这个任务只是循环对一些数据进行相关的查询,并做后续的 insert 。只是数据量很大,并且每个数据要做的对应查询也很多。
    nonoyang
        9
    nonoyang  
    OP
       8 天前
    @whx 这个之前已经调高过一次了。现在是-Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=256m
    -XX:MaxMetaspaceSize=512m
    nonoyang
        10
    nonoyang  
    OP
       8 天前
    @cheng6563 这个我试下。之前是想等挂掉的时候再去拿内存快照,但后来试了两次,发现进程直接无响应了。。。
    fengpan567
        11
    fengpan567  
       8 天前
    是不是文件流没关,服务器上 ulimit -n 检查一下打开文件数的限制是多少
    ChovyChu
        12
    ChovyChu  
       8 天前
    jstat -gc pid 1000 看一下 gc 频率吧,卡住大概率是经常 fgc 了
    nonoyang
        13
    nonoyang  
    OP
       8 天前
    @ChovyChu 测试了几次,发生了 1 、2 次 full gc ,我不太清楚这个频率是否过高。gc 日志我是有记录的,平均 40s 到 1 分多钟左右执行一次新生代的 gc 。full gc 的记录:

    [Full GC (System.gc())
    [PSYoungGen: 8519K->0K(958976K)]
    [ParOldGen: 83126K->75678K(1048576K)]
    91646K->75678K(2007552K),
    [Metaspace: 39477K->39477K(1083392K)],
    0.4594062 secs]
    [Times: user=3.28 sys=0.02, real=0.45 secs]
    huang119412
        14
    huang119412  
       8 天前
    什么都不说,怎么排查,测试机配置和 os 版本,java 版本,框架等。还有系统什么状态?从 Full GC (System.gc())看,这应该回收堆外内存用的。IO 定时任务 CPU 一般占用不会高,最大可能出现在内存和磁盘。我的一个经验是,以前我们测试机用的是机械盘,数据库操作多(随机)的时候,磁盘经常无响应,造成程序假死。
    xylxAdai
        15
    xylxAdai  
       8 天前
    strace ?
    zeni123
        16
    zeni123  
       8 天前
    应该就是内存用多了吧 ParallelGC STW 太长了。增加或者减少堆内存看看从运行时间卡死会不会变化。

    这是 java 几,可以换用 G1 吗,换垃圾回收器解决不了卡死问题,但至少会有响应。至于为什么内存会用多了,可以看看有没有内存泄漏。
    nonoyang
        17
    nonoyang  
    OP
       7 天前
    @zeni123 java 8,我换下试试。也是怀疑是内存用多了,但总是直接卡死,没办法获取卡死时的内存使用情况。我准备实在不行,运行一段时间后,不等卡死,提前 dump 。
    Variazioni
        18
    Variazioni  
       7 天前
    我就遇到过类似的问题。。最后用 jProfiler 查到了原因。。
    试用期 10 天。。应该够用了吧。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3123 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 18ms · UTC 01:11 · PVG 09:11 · LAX 17:11 · JFK 20:11
    ♥ Do have faith in what you're doing.