V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Sponsored by
LinkedIn
不坐班的神仙工作 · 去任何你想去的地方远程,赚一线城市的工资
2000 个不用出门 Social 的全球远程工作,帮助 V2EX 的小伙伴开启全新的工作方式。
Promoted by LinkedIn
choice4
V2EX  ›  Java

一个 JVM 场景

  •  
  •   choice4 · 116 天前 · 2229 次点击
    这是一个创建于 116 天前的主题,其中的信息可能已经有所发展或是发生改变。
    -Xmx2g -Xms2g -Xmn1g java8.

    1. 老年代空间占用很低,20%左右
    1. 新生代 eden 区完全占满(1B 的空闲都没有)
    1. 新生代 from 和 to 区同时不为空, 两者均有 10%左右的占用
    1. cpu 负载已经打满,jstack 和 jmap 均无响应,应用假死
    1. jstack -m 的命令可以得到一些结果,结合 top 看到的线程应该是 jvm 一些 GangWorker 在执行
    1. eden 长时间不释放
    1. jmap -F 会直接导致进程死亡。
    1. gdb 等工具受一些外部因素限制,暂时无法安装,还未找到稳定复现的方法。

    以上这些信息能分析出一些可能的情况吗?
    22 条回复    2022-08-06 14:57:17 +08:00
    choice4
        1
    choice4  
    OP
       116 天前
    dqzcwxb
        2
    dqzcwxb  
       116 天前
    下个 arthas 找到负载高的线程,查到对应代码然后解决就完事了
    RedBeanIce
        3
    RedBeanIce  
       116 天前
    按照百度的 jvm 100%问题排查。去排查呗
    cheng6563
        4
    cheng6563  
       116 天前
    jstack 出不来的话直接用 arthas attach 应该也不行。
    直接项目启动时用 arthas agent 启动,然后持续输出日志吧。
    RedBeanIce
        5
    RedBeanIce  
       116 天前
    @RedBeanIce 我错了。。。楼主已经排查过了。答非所问
    zeni123
        6
    zeni123  
       116 天前
    试一下调大 eden space (*1.5 - 2.0) 看看怎样,eden space 应该和负载高度相关.

    下面是我的猜想,

    假如你经过排查后发现 CPU 占用率不是业务逻辑的线程导致的 那么

    eden 可能释放了 但是又因为高负载被占满了,所以看上去一直不释放。 估计 eden 释放一次只能释放 10% 而不是 90%。YGC 效率不高,造成 YGC 一直工作 CPU 占用率高。
    choice4
        7
    choice4  
    OP
       116 天前
    @zeni123 eden 调大无效,最初始是 768M ,最大调过 -Xms4g -Xmx4g -Xmn2g 年轻代还是会爆满,老年代很空闲
    choice4
        8
    choice4  
    OP
       116 天前
    @dqzcwxb 应用已经假死了,还在执行的线程都是 GangWorker, 同时会有一个 worker 处于 wait 状态,其他的处于满载状态
    xiaohusky
        9
    xiaohusky  
       116 天前
    @RedBeanIce 请问大佬,哪里有参考文档呢?我没谷歌出来,想学习一下
    chendy
        10
    chendy  
       116 天前
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=路径
    等一个 oom 吧,感觉是内存泄漏
    choice4
        11
    choice4  
    OP
       116 天前
    @chendy 都加着呢不会 OOM
    zeni123
        12
    zeni123  
       116 天前
    @choice4

    我的思路其实就是负载太高了 new 的对象多了 内存不够用了。 和调优无关
    GangWorker 就是是 gc 线程吧。gc 线程频繁启动 相当于 rateLimiter 限制你负载的处理速度

    -Xmx2g -Xms2g -Xmn1g 和 -Xms4g -Xmx4g -Xmn2g 它们能处理的负载可能是不一样的 ,你要把负载限制在同一个值再来调整对比。

    以上都是推测
    letianqiu
        14
    letianqiu  
       116 天前
    @choice4 这个其实就是 GC 在 copy 活着的对象。你有没有加上-Xlog:gc=info ,甚至用-Xlog:gc=debug ,看 gc 的 log ?
    alsas
        15
    alsas  
       116 天前
    试试看 G1GC 效果很好
    1194129822
        16
    1194129822  
       116 天前
    java 具体什么小版本?什么垃圾收集器?感觉这个现象很明显是 eden 区直接晋升老年代,老年代有空间但是需要进行内存整理( full gc )才能确保晋升,所以 CPU 一直很高的占用。当然只是可能,具体还要看环境、甚至代码。但是很少有应用需要新生代设置一半堆内存,你把-Xmn1g 去掉或者改小一点看一下。
    choice4
        17
    choice4  
    OP
       116 天前
    @1194129822 最初始的内存配置是 -Xmn768m -Xms2g -Xmx2g ,后来发现是新生代满后就尝试对内存放大,但是没效果,即便新生代最后放到 2g 一样打满
    choice4
        18
    choice4  
    OP
       116 天前
    @1194129822 内存整理的话,他这个时间也太长了,只要达到这个状态,一晚上不管他的话第二天还是打满的 cpu 。。。
    zizon
        19
    zizon  
       116 天前
    @choice4 看这 3s 一次的 jstat 就根本没动过...估计一直反复在 vm operation 里出不来...
    可以复现的话加个 PrintSafepointStatistics 看看是哪些 vm op...

    还有几个 un-document 的参数是控制 vm op 详情和采样频率的,但一时想不起了.

    之前有个类似的 freeze 的案例是有人写了个 jstack -L 的 cron job,一分钟一次...
    -L 导致会单线程爬所有线程的锁关系.

    也可能不是-L,但是个 print lock detail 的相关 flag.
    yidinghe
        20
    yidinghe  
       116 天前 via Android
    这有点过分啊,说明程序正在大量创建临时对象。针对性优化也不难,就是检查哪些对象其实可以留着复用,延长它们的生命周期。
    luozic
        21
    luozic  
       115 天前
    这种可以通过 jmc 工具查看的,visualvm 也行,这种通过 jdk 内置探针查看信息的工具
    https://jdk.java.net/jmc/8/
    https://visualvm.github.io/
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1496 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 43ms · UTC 23:41 · PVG 07:41 · LAX 16:41 · JFK 19:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.