[concurrency-interest] Unbounded thread pool and memory overhead

Peter Levart peter.levart at gmail.com
Mon Aug 25 05:05:57 EDT 2014

On 08/25/2014 07:25 AM, Rohit Reja wrote:
> Hi,
> We are using Executors#newCachedThreadPool() at various places in our product. We recently faced an issue that the threads consumed lots of virtual memory in a machine ( and eventually the system has no memory left) due to lots of threads being created. ( We haven't set the Xss param though).
> I have 2 questions here:-
> 1. Why have this API choose not to have bounded threads ?

Hi Rohit,

Executors#newCachedThreadPool() is just a thin facade over 
ThreadPoolExecutor constructor:

     public static ExecutorService newCachedThreadPool() {
         return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                       60L, TimeUnit.SECONDS,
                                       new SynchronousQueue<Runnable>());

ThreadPoolExecutor class and it's constructor are public API, so you can 
use it directly. Just specify an upper bound on 'maximumPoolSize' 
(instead of Integer.MAX_VALUE), use some other BlockingQueue instead of 
SynchronousQueue (like LinkedBlockingQueue) and you are done.

> What would be the best practices while using unbounded thread pools.

Don't use them in situations where task submission rate can outpace 
processing for extended/unpredictable periods of time or where you don't 
control task submission in some other way. Unbounded thread pool is just 
an optimized variant of approach where you start new Thread for each task.

> 2. How can I build a thread pool with a minimum threads that grows to a max bound and then the task submission blocks?

You might supply a bounded BlockingQueue and when it fills up to it's 
capacity and all 'maximumPoolSize' threads are executing tasks, the 
Executor will start throwing RejectedExecutionException on attempts to 
submit more tasks. No blocking unfortunately. But you could simulate it 
by using a single thread that "take()s" tasks from a front-end bounded 
BlockingQueue and submits them to an executor with a small bounded 
BlockingQueue. If this thread encounters a RejectedExecutionException, 
it sleeps a while and retries... This way you can still get fair 
queue-ing for threads submitting tasks to front-end queue and blocking 
while doing so, just by using for example an 
ArrayBlockingQueue(capacity, true) as a front-end queue.

Regards, Peter

> Thanks,
> Rohit
> On Thursday, August 14, 2014 6:03 PM, Victor Grazi <vgrazi at gmail.com> wrote:
> There's a nice article by Dr. Heinz Kabutz on InfoQ http://www.infoq.com/articles/Hunting-Concurrency-Bugs-1
> Heinz always amazes me!
> Twitter: @vgrazi
> LinkedIn: www.linkedin.com/in/victorgrazi/
> Java Concurrent Animated: http://sourceforge.net/projects/javaconcurrenta/
> Skype: vgrazi2
> Google Plus
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20140825/697a4a6f/attachment-0001.html>

More information about the Concurrency-interest mailing list