SpringBoot 程序运行中突然中止, JVM 退出

5 天前
 Geekerstar

程序退出后,生成了一个 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:

http://bugreport.java.com/bugreport/crash.jsp

2247 次点击
所在节点    Java
48 条回复
Geekerstar
4 天前
@ZZ74 #20 感谢大佬,AbstractFramedChannel.flushSenders()应该是 undertow 底层推送 ws 的时候调用的,系统中有 websocket 推送,数据量和频次很高,快的话几毫秒一次。但是据说出问题那会儿没有停留在有 ws 推送的页面。flushSenders 是给 web 客户端发送数据。
Geekerstar
4 天前
@ZZ74 #20 查了一下,Undertow 使用 Java NIO ( non-blocking I/O )来处理 WebSocket 和 HTTP 连接。NIO 会使用 ByteBuffer ,其中包括堆外内存( Direct ByteBuffer )。有可能和这个有关系么?
Solace202
4 天前
肯定是代码写的有问题,建议把最新版本和上次版本之间提交的代码 review 下,对于循环、查库 留意下,大概率是内存不够直接挂了
hideon
4 天前
有没有 heapdump? 看起来崩溃前存在频繁 GC 和对象生成, 结合使用 ws, 是不是瞬时连接增大导致的?
Geekerstar
4 天前
@hideon 没有手动 dump ,因为当时 JVM 直接挂了。也没有自动生成 Dump 文件。您说的这个 ws 瞬间连接增大有一定道理,但是我们这个是内网使用,不会有很多人同时使用。以前有过 OOM ,是因为 ws 连接一直没释放,导致后端有引用在无法回收部分垃圾。但是目前已经加了五分钟自动断开重连 ws 的机制了。ws 推送的频次和数据量确实很高。毫秒级的。
Geekerstar
4 天前
操作系统是 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.
hrapunzel
4 天前
可能是堆外内存爆了
ZZ74
4 天前
@Geekerstar 很可能啊,发送的是序列化后的 java 对象还是文件?一般来说 java 代码写入超过 byebuff 大小只会有 runtime 异常,但如果直接是文件的话就不一定了。比如发送时文件大小比之前分配好 bytebuff 时大了导致越界。
另外 XNIO-1 I/O-6" [_thread_in_Java 其他都是_thread_in_native 有一定并发可能
Geekerstar
4 天前
@hrapunzel 这个服务器 128g ,目前只用了十多 G
Geekerstar
4 天前
@ZZ74 #28 我们发送的是 JSON 的字符串,不是文件。您最后一句话是啥意思呢?是指可能是因为并发导致的吗
ZZ74
4 天前
@Geekerstar XNIO-1 I/O-x 这种线程理解没错的话 应该都是给 web 客户端发送数据的吧?
你可以比较下是不是每次崩 ,那个线程都是_thread_in_Java ,如果是的话考虑下大字符串 毕竟这个线程还没执行 native 代码。
因为你说你们没有操作 byebuff 那也有可能 undertow 高并发有 bug ,导致操作了正在被其他执行 native 代码的 byebuff 被这个线程用到了。
cyningxu
4 天前
太深奥了不懂,但还是每层楼都看完了,真的很喜欢这种氛围,大家一起帮忙解决问题,已经很久没在中文互联网看到这种场景了,现在大多都是冷嘲热讽。
hrapunzel
4 天前
@Geekerstar #29 堆外内存默认是 -Xmx 的大小, -XX:MaxDirectMemorySize 用这个参数指定一下
Geekerstar
4 天前
@hrapunzel #33 好的,我试一下,堆外内存默认 xmx 一样的 2g ,感觉 2g 应该够用了。我查了一下:如果 JVM 试图分配堆外内存(例如通过 ByteBuffer.allocateDirect()分配直接内存),但操作系统的内存资源已经耗尽,JVM 通常不会直接触发 SIGSEGV ,而是抛出 java.lang.OutOfMemoryError: Direct buffer memory 。JVM 本身一般不会直接因为堆外内存不足触发 SIGSEGV ,但如果程序使用了 JNI 、本地库或者使用了不安全的操作(例如 Unsafe 类),在处理内存时可能会导致 SIGSEGV
Geekerstar
4 天前
@cyningxu 是的,非常感谢大家,我也喜欢这种氛围。
suwu
4 天前
@cyningxu +1 ,没有 dump 我就不会分析了。。。
xuanbg
4 天前
JVM 退出的话基本就是内存不足造成的,怕是接收到什么大数据,把分配给 JVM 的内存撑爆了
D3EP
4 天前
@Geekerstar #17 作为在互联网公司中间件团队的我只能说,没准儿是 undertow 或者 JDK 有 bug 。
LeegoYih
4 天前
遇到过有个生成图形验证码服务被 OOM Killer 杀过一次,没有 dump
jarvison
4 天前
太深奥了不懂,但还是每层楼都看完了,真的很喜欢这种氛围,大家一起帮忙解决问题,已经很久没在中文互联网看到这种场景了,现在大多都是冷嘲热讽。

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

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

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

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

© 2021 V2EX