一个 JVM 场景

2022-06-02 15:00:06 +08:00
 choice4
-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 等工具受一些外部因素限制,暂时无法安装,还未找到稳定复现的方法。

以上这些信息能分析出一些可能的情况吗?
3196 次点击
所在节点    Java
22 条回复
choice4
2022-06-02 15:53:50 +08:00
dqzcwxb
2022-06-02 16:31:09 +08:00
下个 arthas 找到负载高的线程,查到对应代码然后解决就完事了
RedBeanIce
2022-06-02 17:12:05 +08:00
按照百度的 jvm 100%问题排查。去排查呗
cheng6563
2022-06-02 17:14:00 +08:00
jstack 出不来的话直接用 arthas attach 应该也不行。
直接项目启动时用 arthas agent 启动,然后持续输出日志吧。
RedBeanIce
2022-06-02 17:18:35 +08:00
@RedBeanIce 我错了。。。楼主已经排查过了。答非所问
zeni123
2022-06-02 17:59:58 +08:00
试一下调大 eden space (*1.5 - 2.0) 看看怎样,eden space 应该和负载高度相关.

下面是我的猜想,

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

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

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

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

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

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

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

也可能不是-L,但是个 print lock detail 的相关 flag.
yidinghe
2022-06-02 23:26:29 +08:00
这有点过分啊,说明程序正在大量创建临时对象。针对性优化也不难,就是检查哪些对象其实可以留着复用,延长它们的生命周期。

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

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

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

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

© 2021 V2EX