HttpURLConnection上的Tomcat内存泄漏警告

问题描述:

我在Tomcat 8.5中收到以下警告,我不确定是否可以忽略

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)

它在connect上的以下代码中发生:

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);
}

我应该在关闭InputStream的情况下添加一个finally:

Should I add a finally with closing the InputStream:

http.getInputStream().close();

还是应该将此代码升级/转换为使用URIBuilderHttpHost?

Or this code should be upgraded/converted to use URIBuilder and HttpHost?

编辑 使用Spring的@Scheduled

EDIT The code executed every X seconds using Spring's @Scheduled

您正在Tomcat中使用@Scheduled生成线程.您必须确保在ServletContext被销毁时这些线程将完成,例如取消部署WAR后,Tomcat会警告您. HTTP请求代码无关,因为URLConnection不会启动新线程来执行请求.

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.

使Tomcat满意的一种方法是使用守护程序线程,如此答案中所述.可以使用自定义的taskScheduler bean:

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;
          }
        });
  }

}