-
Notifications
You must be signed in to change notification settings - Fork 5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't allow idle threads to live forever #612
Conversation
This seems like a good idea (although no idea about the best default idle value). It was like this since the code was initially added. |
My reading of the code is that the AsynchronousChannelProvider submits tasks that never end to the executor so this patch has no effect. The purpose of the Executor is to replace any threads that fail. Local testing appears to confirm this. Unless I've missed something (always possible) I think this PR (and the associated BZ issue) needs to be closed without being merged. |
I'll have a further look at this tomorrow. The situation I have is hundreds of idle threads. Potentially a configurable solution using virtual threads would mitigate the issue. |
A thread dump would be helpful. |
Hum, this is the websocket client and it is using NIO2, so that executor would be used internally for all things that are run asynchronously for IO like calling completion handlers and so on. |
I've done a smaller thread ump (attached). I can find this documentation on the
So in short this threadpool is only used for completion callbacks. It seems like the decision was made to have a synchronous queue with an unbounded number of threads, rather than have a bounded number of threads and an unbounded queue. To me this seems like the wrong way round, interested to hear thoughts? There is no good reason to keep the threads running forever that I can see based on the documentation and also other implementations that call the These threads are globally shared, however, looking at the dump there are two Thanks all |
The thread dump confirms the earlier analysis. The |
The default |
From https://bz.apache.org/bugzilla/show_bug.cgi?id=66581
Currently the ExecutorService used for this is as such:
ExecutorService executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, Long.MAX_VALUE, TimeUnit.MILLISECONDS, new SynchronousQueue<>(), new AsyncIOThreadFactory());
This means that the threads never terminate and are spawned whenever a thread is not available, which for a server under a spike of load spawns many threads which never exit, consuming system resources indefinitely.
I would suggest that a saner idle timeout than Long.MAX_VALUE should be used, such as 60 seconds, unless there is a good reason I am unaware of as to why such threads should never die.