升级到Wildfly 18后出现Direct buffer memory内存溢出问题求助
根因分析
你遇到的直接内存泄漏是Wildfly 17~19版本区间的已知Bug,核心诱因是其内置的Undertow 2.0.x、XNIO 3.7.x组件的缓冲区池回收逻辑缺陷:
- 当服务处理大量短连接请求时,
ByteBufferSlicePool分配的切片缓冲区没有正确解除和父缓冲区的引用关联,导致整组直接缓冲区被XNIO内部引用链长期持有,无法被GC回收 - 你观测到的1544个相同大小的DirectByteBuffer对象就是典型的切片池泄漏特征,这类对象不属于堆内存GC的常规清理范围,因此手动GC几乎没有效果
- Wildfly 13使用的是XNIO 3.6.x、Undertow 1.4.x版本,不存在该引用逻辑缺陷,因此旧版本运行正常
替代解决方案(无需关闭直接缓冲区牺牲性能)
你可以按优先级选择以下方案,避免直接关闭直接缓冲区带来的性能损耗:
- 优先升级Wildfly到18.0.4及以上的18系列维护版,或直接升级到21.0.0正式版,该Bug已经在后续版本中被官方修复,是风险最低的解决方法
- 如果暂时无法升级版本,可以调整默认缓冲区池的最大容量参数,限制池化内存的上限:
该配置将直接缓冲区池的最大容量限制为10MB,超过上限的缓冲区会被直接释放而不是进入池化队列,从根源上避免泄漏资源累积/subsystem=io/buffer-pool=default:write-attribute(name=max-size,value=10485760) - 调整IO线程配置:你提到的
ioThreads是XNIO的底层IO处理线程数,和业务worker线程池是完全独立的组件,默认值为CPU核心数2,你当前配置的12属于合理范围。如果服务峰值连接量不高,可以将ioThreads调整为CPU核心数2,减少缓冲区池的实例数量,降低泄漏累积速度
相关说明
- 该问题属于Undertow的HTTP读监听器处理半关闭连接时的资源泄漏,和WebSocket服务无关,即使未开启WebSocket也会触发
- 不存在JVM层面的Bug,你测试的Java 8和更高版本都不会触发该问题,完全是Wildfly内置组件的逻辑缺陷
内容的提问来源于stack exchange,提问作者Lonzak
相关产品推荐
相关产品推荐

