程序退出后,生成了一个 hs_err_pid1301132.log 文件,前面的内容如下,可以根据这个判断出是什么原因导致的吗?

A fatal error has been detected by the Java Runtime Environment:

SIGSEGV (0xb) at pc=0x000072ca636529ce, pid=1301132, tid=0x000072c7af5ff640

JRE version: Java(TM) SE Runtime Environment (8.0_371) (build 1.8.0_371-b11)
Java VM: Java HotSpot(TM) 64-Bit Server VM (25.371-b11 mixed mode linux-amd64 compressed oops)
Problematic frame:
J 39882 C2 sun.nio.ch.IOUtil.write(Ljava/io/FileDescriptor;[Ljava/nio/ByteBuffer;IILsun/nio/ch/NativeDispatcher;)J (509 bytes) @ 0x000072ca636529ce [0x000072ca636528a0+0x12e]

Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again

If you would like to submit a bug report, please visit:
bugreport.java.com/bugreport/crash.jsp

程序有大量的 CPU 和 IO 操作。这个是当时的监控截图,大概是 8:53 停掉的。 imgse.com/i/pAGLDy9 imgse.com/i/pAGLBQJ

操作系统是 ubuntu ,检查 syslog 日志,发现一个信息,不知道是否有关联:1 、程序最后一行 info 日志时间是,2024-10-09 08:52:57.251 ,无错误日志。2 、检查 Syslog 日志,发现同一秒有下面的日志:Oct 9 08:52:57 lenovo-07 systemd[1]: session-2106.scope: Deactivated successfully.Oct 9 08:52:57 lenovo-07 systemd[1]: session-2106.scope: Consumed 2w 1d 21h 28min 5.200s CPU time.

ulimit -a 看看系统有没有做参数优化

看看你的 JVM 参数和配置呢

jvm 没配置 core dump ,这点日志看不出什么。看谷歌结果貌似是 netty 报的错,检查一下代码或者加 core dump 参数后等复现吧

没有优化过:real-time non-blocking time (microseconds, -R) unlimitedcore file size (blocks, -c) 0data seg size (kbytes, -d) unlimitedscheduling priority (-e) 0file size (blocks, -f) unlimitedpending signals (-i) 513419max locked memory (kbytes, -l) 16438992max memory size (kbytes, -m) unlimitedopen files (-n) 1024pipe size (512 bytes, -p) 8POSIX message queues (bytes, -q) 819200real-time priority (-r) 0stack size (kbytes, -s) 8192cpu time (seconds, -t) unlimitedmax user processes (-u) 513419virtual memory (kbytes, -v) unlimitedfile locks (-x) unlimited

-Xmx2048m -Xms2048m -XX:+UseG1GC 没有做其他的优化

好的,感谢

是不是被 Linux kill 了?

可以看下日志,cat /var/log/messages | egrep -T -C10 Kill

jvm 退出最常见的就是内存不够了,要么是堆内存,要么是堆外内存。 结合 ByteBuffer 和 SIGSEGV ,堆外可能性最大。具体的得描述下你的程序是干嘛的,以及更多 log

我的错误和这个很像,难道真的是 Netty 的问题? github.com/netty/netty/issues/4206

#7 应该不是,查了系统日志没发现啥问题

我从监控平台看了下内存那些都很正常的呢? imgse.com/i/pAGLDy9 imgse.com/i/pAGLBQJ 程序有大量的 IO 和 CPU 操作,用的 undertow 框架。

可能是磁盘空间不足或者是打开的文件数据过多了

你贴的 gihub 的例子就是 memory 问题啊,而且人家也给出了 netty 配置。 hs_err_pid1301132.log 文件内容远不止于此,github 上面就详细多了,能看到 oom 报错还有Event: 984.476 GC heap before ParOldGen total 2796544K, used 2796216K object space 2796544K, 99% used 你那个监控中的 45 到 9 点那一下 memory 的异常大量分配很值得怀疑,之后没数据了,持续 full GC 崩溃了导致没数据了吧

#14 大佬能否帮忙分析一下呢?实在找不到问题了,这是几张完整的监控截图。大概八点四五十的时候用户开始使用的,之后没数据是因为 JVM 退出了。 imgse.com/i/pAJpwrD imgse.com/i/pAJp0qe imgse.com/i/pAJpdKO这是 hs_err_pid1301132.log 文件pan 点 baidu 点 com/s/1hZ5Fb8Nir458vSiS14XY-Q 提取码: cgpp

程序有手动控制 Netty ByteBuf 的逻辑吗?之前接手过一个 RPC 框架,在一些业务场景下出现类似的 Segment Fault ,发现是在某个地方释放了 ByteBuf ,但后面又往里写数据最终 core 掉了。

没有哦,我们程序有 websocket 推送,而且 web 框架是用的 undertow ,好像底层有 netty ,但是没有直接在业务代码里操作 netty

磁盘还有几个 T ,文件句柄看日志也正常范围

ulimit 只对“当前 shell”有效。查看别的进程的 limit 需要看/proc

SEGV_MAPERR 错误,崩溃前平凡 FGC ,但是内存能下来,看起来有临时大对象。AbstractFramedChannel.flushSenders()的时候崩了。我不知道 undertow 用的堆内还是堆外。有可能是因为 ByteBuf 大小有限 把 java 大对象写入 ByteBuf 时导致的。也不排除 16 楼说的。你可以结合你的系统特点看看。看起来是个物联网数据采集系统不知道 flushSenders 是在给设备发数据还是提供查询。

#20 感谢大佬,AbstractFramedChannel.flushSenders()应该是 undertow 底层推送 ws 的时候调用的,系统中有 websocket 推送,数据量和频次很高,快的话几毫秒一次。但是据说出问题那会儿没有停留在有 ws 推送的页面。flushSenders 是给 web 客户端发送数据。

#20 查了一下,Undertow 使用 Java NIO ( non-blocking I/O )来处理 WebSocket 和 HTTP 连接。NIO 会使用 ByteBuffer ,其中包括堆外内存( Direct ByteBuffer )。有可能和这个有关系么?

肯定是代码写的有问题,建议把最新版本和上次版本之间提交的代码 review 下,对于循环、查库 留意下,大概率是内存不够直接挂了

有没有 heapdump? 看起来崩溃前存在频繁 GC 和对象生成, 结合使用 ws, 是不是瞬时连接增大导致的?

没有手动 dump ,因为当时 JVM 直接挂了。也没有自动生成 Dump 文件。您说的这个 ws 瞬间连接增大有一定道理,但是我们这个是内网使用,不会有很多人同时使用。以前有过 OOM ,是因为 ws 连接一直没释放,导致后端有引用在无法回收部分垃圾。但是目前已经加了五分钟自动断开重连 ws 的机制了。ws 推送的频次和数据量确实很高。毫秒级的。

操作系统是 ubuntu ,检查 syslog 日志,发现一个信息,不知道是否有关联:1 、程序最后一行 info 日志时间是,2024-10-09 08:52:57.251 ,无错误日志。2 、检查 Syslog 日志,发现同一秒有下面的日志:Oct 9 08:52:57 lenovo-07 systemd[1]: session-2106.scope: Deactivated successfully.Oct 9 08:52:57 lenovo-07 systemd[1]: session-2106.scope: Consumed 2w 1d 21h 28min 5.200s CPU time.

可能是堆外内存爆了

很可能啊,发送的是序列化后的 java 对象还是文件?一般来说 java 代码写入超过 byebuff 大小只会有 runtime 异常,但如果直接是文件的话就不一定了。比如发送时文件大小比之前分配好 bytebuff 时大了导致越界。另外 XNIO-1 I/O-6" [_thread_in_Java 其他都是_thread_in_native 有一定并发可能

这个服务器 128g ,目前只用了十多 G

#28 我们发送的是 JSON 的字符串,不是文件。您最后一句话是啥意思呢?是指可能是因为并发导致的吗

XNIO-1 I/O-x 这种线程理解没错的话 应该都是给 web 客户端发送数据的吧? 你可以比较下是不是每次崩 ,那个线程都是_thread_in_Java ,如果是的话考虑下大字符串 毕竟这个线程还没执行 native 代码。因为你说你们没有操作 byebuff 那也有可能 undertow 高并发有 bug ,导致操作了正在被其他执行 native 代码的 byebuff 被这个线程用到了。

太深奥了不懂,但还是每层楼都看完了,真的很喜欢这种氛围,大家一起帮忙解决问题,已经很久没在中文互联网看到这种场景了,现在大多都是冷嘲热讽。