Note that there are some explanatory texts on larger screens.

plurals
  1. POThreads in newCachedThreadPool() are always waiting and the thread count is always increasing
    primarykey
    data
    text
    <p>I meet a problem that tomcat throws <code>OutOfMemoryError</code>:</p> <pre><code>SEVERE: Servlet.service() for servlet DataPortServlet threw exception java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.addIfUnderMaximumPoolSize(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.execute(Unknown Source) at java.util.concurrent.AbstractExecutorService.submit(Unknown Source) ... </code></pre> <p>What I want to do is: when data received in a servlet, send the received data to another server through <code>HttpClient</code>, related code:</p> <p>servlet:</p> <pre><code>protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { ... byte[] data = getDataFromRequest(request); // pseudo code, get data CallableLogSender sender = new CallableLogSender(data); pool.submit(sender); // here the pool is the one instantiated at the start of application, singleton ... } </code></pre> <p>class implements <code>Callable</code> interface:</p> <pre><code>public class CallableLogSender implements Callable&lt;Integer&gt; { private byte[] content; public CallableLogSender(byte[] content) { this.content = content; } @Override public Integer call() { try { String uri = getRemoteServerUri(); // pseudo code, get uri here HttpPost request = new HttpPost(uri); request.setHeader("Content-Type", "application/x-www-form-urlencoded"); request.setEntity(new ByteArrayEntity(content)); HttpClient httpClient = getHttpClient(); // pseudo code, get cached http client, it is a singleton instance HttpResponse response = httpClient.execute(request); statusCode = response.getStatusLine().getStatusCode(); EntityUtils.consume(response.getEntity()); } catch(Exception e) { // log error here... } finally { request.releaseConnection(); } return statusCode; } } </code></pre> <p>As shown in the code, I <code>submit</code> a task to thread pool every time when a client connected, then I use jProfiler to monitor tomcat, it shows that the thread number in the pool is always increasing!!! and all the threads are in <code>waiting</code> state, so when the thread number exceeds the threshold, <code>OutOfMemoryError</code> occurs.</p> <p>In my opinion, the threads should be reused and the thread number should be stable, at least not always increase, I don't know if it is because the <code>waiting</code> state makes the pool think that the threads are all "busy", so new thread needs to be created.</p> <p>So any suggestion about how to make the pool reuse the threads and not always create new thread?</p> <p>Thanks in Advance, Kelvin</p> <hr> <p>edit: Finally I find the root cause is because the http request takes too long to respond, so if tasks are submitted in a burst, the thread count will be always increasing, since one task takes too long to complete.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload