2

在下面的 Spring Integration 文档的 7.1.7 异步轮询部分中,解释了如果 Poller 和 TaskExecutor 不协调可能会发生内存泄漏。但我不明白。

http://docs.spring.io/autorepo/docs/spring-integration/3.0.x/reference/html/messaging-endpoints-chapter.html#async-polling

<int:service-activator input-channel="publishChannel" ref="myService">
    <int:poller receive-timeout="5000" task-executor="taskExecutor" fixed-rate="50"/>
</int:service-activator>

<task:executor id="taskExecutor" pool-size="20" queue-capacity="20"/>

上面的配置演示了其中一种不协调的配置。

即使所有线程都被阻塞等待新消息到达或超时到期,轮询器仍会继续调度新任务。假设有 20 个线程执行 5 秒超时的任务,它们将以每秒 4 个的速率执行(5000/20 = 250ms)。但是,新任务以每秒 20 个的速度被调度,因此任务执行器中的内部队列将以每秒 16 个的速度增长(当进程空闲时),所以我们基本上有内存泄漏。

处理此问题的方法之一是将 > 任务执行器的 queue-capacity 属性设置为 0。

有人可以详细说明一下。

以下是我对上述代码的理解:

pool-size 为 20 - 因此将执行 20 个线程。

接收超时为 5 秒:因此 20 个线程将有 5 秒的时间来完成任务。

固定速率为 50 毫秒 - 因此新任务以每秒 20 个的速率进行调度。

我有几个问题:

Q. 如果执行 20 个线程的时间超过 5 秒会怎样?

Q. 在文档中,它所说的任务将以每秒 4 个的速度执行。但是,有些任务可能会在不到 4 秒的时间内运行,有些则需要更多时间。

Q. 它是如何导致内存泄漏的?如果没有可用的线程和队列,Executor 会根据拒绝策略拒绝它。

问:将 queue-capacity 设置为 0 有何帮助?根据我的理解,如果所有线程都忙,那么 Executor 会将它们放入队列中,直到达到队列容量。

4

1 回答 1

0

文档不正确 - 只有当您有一个无界队列并且消息处理跟不上时,才会出现内存泄漏。我打开了一个JIRA 问题来纠正它。

于 2015-07-30T13:22:00.413 回答