Netty无效对象数组问题:OpenJDK11 Java应用内存占用异常咨询
问题分析与解答
这是Netty内存池机制相关的已知场景,并非严格意义上的内存泄漏,分两类情况说明:
1. 关联Finalizer.unfinalized的内存块(18,576Kb)
这是Netty PoolThreadCache 依赖Finalizer机制回收导致的临时内存保留:
PoolThreadCache实现了Finalizable接口,当持有该缓存的线程退出时,Finalizer线程会负责清理缓存中的内存区域。- 但Finalizer线程的调度存在延迟,应用启动后短时间内,这些未被及时清理的
MpscArrayQueue.buffer(空Object数组)会被Finalizer队列持有,表现为未释放内存。 - 这是Netty 4.1.x早期版本的常见现象,社区已明确这是设计机制带来的临时内存占用,后续版本(4.1.50.Final及以上)优化了
PoolThreadCache的回收逻辑,不再依赖Finalizer,改为线程退出时主动清理。
2. 关联Log4j JMX线程池的内存块(5,031Kb)
这是Netty Recycler对象复用机制的正常缓存:
- Log4j的JMX Server线程池使用了Netty的
FastThreadLocalThread,Netty的Recycler(用于ByteBuf对象复用)会通过WeakOrderQueue缓存已回收的对象句柄。 - 这些空Object数组是Recycler队列的缓存结构,用于减少对象创建开销,属于性能优化手段。只要线程池线程存活,这些缓存会被保留,但当内存压力增大或线程闲置时,弱引用关联的队列会被GC自动清理。
总结
这两类都是Netty内存池机制相关的已知行为,若内存占用未持续增长到影响应用运行,无需过度担忧。若需优化:
- 升级Netty到4.1.50.Final及以上版本,解决Finalizer依赖导致的内存延迟释放问题。
- 调整Netty内存池参数:通过系统属性
io.netty.allocator.tinyCacheSize减小tiny缓存的容量,平衡内存占用与性能。 - 若不需要Log4j JMX监控,可关闭该功能以释放相关线程的缓存内存。
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

