问题
I have the following warning in Tomcat 8.5 I'm not sure I can ignore
WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [AppName] appears to have started a thread named [pool-20-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
java.net.SocketInputStream.read(SocketInputStream.java:171)
java.net.SocketInputStream.read(SocketInputStream.java:141)
sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
sun.security.ssl.InputRecord.read(InputRecord.java:503)
sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
It happens on connect
in the following code:
URL url = new URL(MY_URL);
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection) con;
http.setRequestMethod("POST");
http.setDoOutput(true);
http.setFixedLengthStreamingMode(out.length);
http.setRequestProperty("Content-Type", "application/json");
http.connect();
try (OutputStream os = http.getOutputStream()) {
os.write(out);
}
Should I add a finally with closing the InputStream
:
http.getInputStream().close();
Or this code should be upgraded/converted to use URIBuilder
and HttpHost
?
EDIT
The code executed every X seconds using Spring's @Scheduled
回答1:
You are using @Scheduled
within Tomcat to spawn threads. You must ensure that these threads will finish when the ServletContext
is destroyed e.g. WAR being undeployed, Tomcat warns you about this. The HTTP request code is unrelated as URLConnection
doesn't start new threads to perform the request.
One way to make Tomcat happy is to use daemon threads, as explained in this answer. This can be done with custom taskScheduler
bean:
@Configuration
@EnableScheduling
public class TaskConfiguration {
@Bean(destroyMethod = "shutdown")
public Executor taskScheduler() {
return Executors.Executors.newFixedThreadPool(4,
new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
}
});
}
}
来源:https://stackoverflow.com/questions/51818025/tomcat-memory-leak-warning-on-httpurlconnection