HttpURLConnectionののソケットがリークしています

エミール:

私は、Linux上でのOpenJDK 11を使用していると私は確信してのHttpURLConnection適切に閉じられているで行われ、すべての私のWebリクエストを行う必要があると記述子が開いて任意のファイルを保持しません。

Oracleのマニュアルでは、使用することを伝えcloseInputStreamAndroidのマニュアルを使用するように指示disconnectHttpURLConnectionオブジェクト。

私はまた、設定Connection: closehttp.keepAliveするfalse接続のプールを避けるために。

これは、プレーンで動作するように思えるのHTTP要求が暗号化されていないHTTPSその応答で送信された要求の非チャンクエンコーディングを唯一のGCは、閉じた接続をクリーンアップするようです。

このサンプルコード:

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;

public class Test {
    private static int printFds() throws IOException {
        int cnt = 0;
        try (Stream<Path> paths = Files.list(new File("/proc/self/fd").toPath())) {
            for (Path path : (Iterable<Path>)paths::iterator) {
                System.out.println(path);
                ++cnt;
            }
        }
        System.out.println();
        return cnt;
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        System.setProperty("http.keepAlive", "false");
        for (int i = 0; i < 10; i++) {
            // Must be a https endpoint returning non-chunked response
            HttpURLConnection conn = (HttpURLConnection) new URL("https://www.google.com/").openConnection();
            conn.setRequestProperty("Connection", "close");
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            while (in.readLine() != null) {
            }
            in.close();
            conn.disconnect();
            conn = null;
            in = null;
        }

        Thread.sleep(1000);
        int numBeforeGc = printFds();

        System.gc();
        Thread.sleep(1000);
        int numAfterGc = printFds();
        System.out.println(numBeforeGc == numAfterGc ? "No socket leaks" : "Sockets were leaked");
    }
}

この出力は、出力します。

/proc/self/fd/0
/proc/self/fd/1
/proc/self/fd/2
/proc/self/fd/3
/proc/self/fd/4
/proc/self/fd/5
/proc/self/fd/9
/proc/self/fd/6
/proc/self/fd/7
/proc/self/fd/8
/proc/self/fd/10
/proc/self/fd/11
/proc/self/fd/12
/proc/self/fd/13
/proc/self/fd/14
/proc/self/fd/15
/proc/self/fd/16
/proc/self/fd/17
/proc/self/fd/18
/proc/self/fd/19

/proc/self/fd/0
/proc/self/fd/1
/proc/self/fd/2
/proc/self/fd/3
/proc/self/fd/4
/proc/self/fd/5
/proc/self/fd/9
/proc/self/fd/6
/proc/self/fd/7
/proc/self/fd/8

Sockets were leaked

A HTTP URLに変更すると、GCせずに期待通りのソケットが正しく閉じます。

/proc/self/fd/0
/proc/self/fd/1
/proc/self/fd/2
/proc/self/fd/3
/proc/self/fd/4
/proc/self/fd/5
/proc/self/fd/6

/proc/self/fd/0
/proc/self/fd/1
/proc/self/fd/2
/proc/self/fd/3
/proc/self/fd/4
/proc/self/fd/5
/proc/self/fd/6

No socket leak

OpenJDKの11と12の両方でテスト私が何かを欠場かこれはバグでいましたか?

エミール:

:すべての後にかかわる問題であることが判明https://bugs.openjdk.java.net/browse/JDK-8216326

shutdownInput今で置き換えられcloseた最新のJDK 11および13(ただし12)のビルドで。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=230095&siteId=1