Spring Integration应用内存泄漏求助:Poller引发对象无法释放
Spring Integration Poller 内存泄漏问题解决
问题背景
我有一个Spring Integration应用,包含带requestChannel的网关及消费通道消息的@ServiceActivator。该@ServiceActivator通过Poller轮询获取消息,配置如下:
@ServiceActivator(inputChannel = "inputChannel", poller = @Poller(fixedDelay = "10", maxMessagesPerPoll = "50", taskExecutor = "myExecutor"))
对应的任务执行器XML配置:
<task:executor id="myExecutor" pool-size="1" rejection-policy="DISCARD"/>
运行时发现大量java.util.concurrent.LinkedBlockingQueue$Node、org.springframework.integration.util.ErrorHandlingTaskExecutor$$Lambda和org.springframework.integration.endpoint.AbstractPollingEndpoint$$Lambda对象无法被GC回收,即使队列无新消息仍持续生成。禁用@ServiceActivator后该现象消失,确认是Poller导致的内存泄漏。
解决办法
- 增大Poller的fixedDelay间隔:当前
fixedDelay="10"表示每10毫秒轮询一次,高频轮询会持续触发任务提交,大量Lambda和队列节点被快速创建。根据业务需求将间隔调大,比如改为fixedDelay="100"或更合理的值,减少无意义的轮询操作。 - 优化任务执行器配置:
- 更换拒绝策略:
DISCARD策略会直接丢弃无法执行的任务,结合单线程池(pool-size="1")和高频轮询,会导致大量任务被丢弃却仍不断有新任务提交。建议改为CALLER_RUNS,让提交任务的Poller线程直接执行任务,避免无效任务对象堆积; - 限制队列容量:默认
task:executor使用无界LinkedBlockingQueue,会导致LinkedBlockingQueue$Node无限制创建。显式指定队列容量,比如:<task:executor id="myExecutor" pool-size="1" queue-capacity="10" rejection-policy="CALLER_RUNS"/>
- 更换拒绝策略:
- 添加Poller的receiveTimeout参数:在
@Poller中配置receiveTimeout,指定从通道获取消息的超时时间,无消息时Poller会及时结束当前轮询,减少资源占用。示例:@ServiceActivator(inputChannel = "inputChannel", poller = @Poller(fixedDelay = "100", maxMessagesPerPoll = "50", taskExecutor = "myExecutor", receiveTimeout = "50")) - 移除异步执行配置(非必要场景):如果业务不需要异步处理消息,直接去掉
taskExecutor配置,让Poller同步执行,避免线程池和异步任务带来的对象创建开销:@ServiceActivator(inputChannel = "inputChannel", poller = @Poller(fixedDelay = "100", maxMessagesPerPoll = "50"))
内容的提问来源于stack exchange,提问作者jalogar
相关产品推荐
相关产品推荐

