I have an tomcat webapp where I use a java executor to execute some runnables.
First I allocate the executor service from my executor instance like this:
executorService = Executors.newFixedThreadPool(nThreads, new MyThreadFactory(threadFactoryName))
Then, I launch task using the executor service:
executorService.execute(new MyRunnable);
Then, it seems to work. But my problem is, I am chasing some sort of leak where I get this error after a while of running the server:
Caused by: java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:640)
at java.util.concurrent.ThreadPoolExecutor.addIfUnderCorePoolSize(ThreadPoolExecutor.java:703)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:652)
at something.server.ThreadExecutor.execute(MyRunnable.java:91)
I used the java VisualVM on tomcat instance to trace the thread allocation. I see that when I call ‘newFixedThreadPool’ I see ‘nThreads’ new threads. But after their job is done, I see the state of the threads to be on ‘wait’.
Is that normal? I don’t believe it is, I know the runnables finish their job but the executor service never frees the threads. What can I do to free them, or am I completely out of scope?
I think you are instantiating a new
ExecutorServicefor every request, or something like that.You should either instantiate only one
ExecutorService, and reuse it, or callshutdown()on the service after you have finished submitting tasks. Theshutdownfunction will wait for the tasks to finish, and then free the threads.