2

以下の Spring Integration doc の 7.1.7 Asynchronous polling セクションでは、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"/>

上記の構成は、調整されていない構成の 1 つを示しています。

すべてのスレッドがブロックされ、新しいメッセージが到着するか、タイムアウトが期限切れになるのを待っている場合でも、ポーラーは新しいタスクをスケジュールし続けます。5 秒のタイムアウトでタスクを実行する 20 のスレッドがあるとすると、それらは 1 秒あたり 4 の割合で実行されます (5000/20 = 250 ミリ秒)。ただし、新しいタスクは 1 秒あたり 20 の割合でスケジュールされているため、タスク エグゼキューターの内部キューは (プロセスがアイドル状態の間) 1 秒あたり 16 の割合で増加するため、基本的にメモリ リークが発生します。

これを処理する方法の 1 つは、Task Executor の queue-capacity 属性を 0 に設定することです。

誰か詳しく教えてください。

上記のコードに対する私の理解は次のとおりです。

pool-size は 20 であるため、20 個のスレッドが実行されます。

receive-timeout は 5 秒です。したがって、タスクを完了するために 20 のスレッドに 5 秒が与えられます。

固定レートは 50 ミリ秒です。したがって、新しいタスクは 1 秒あたり 20 のレートでスケジュールされます。

いくつか質問があります:

Q. 20 スレッドの実行に 5 秒以上かかるとどうなりますか?

Q. ドキュメントでは、前述のタスクは 1 秒あたり 4 つの割合で実行されます。ただし、4 秒未満で実行されるタスクもあれば、それ以上かかるタスクもあります。

Q. メモリ リークはどのように発生しますか? 使用可能なスレッドとキューがない場合、Executor は代わりに拒否ポリシーに従ってそれを拒否します。

Q. queue-capacity を 0 に設定すると、どのように役立ちますか? 私の理解によると、すべてのスレッドがビジーである場合、エグゼキューターはキュー容量に達するまでそれらをキューに入れます。

4

1 に答える 1