1. 程式人生 > >使用HttpURLConnection時遇到的資源未釋放的問題

使用HttpURLConnection時遇到的資源未釋放的問題



今天自己寫了一個壓力測試的小程式,同時啟100個執行緒,每個執行緒都序列地訪問應用伺服器上的一個jsp頁面200次。在程式運行了一會兒以後,問題來了:

java.net.SocketException: No buffer space available (maximum connections reached?): connect
 at java.net.PlainSocketImpl.socketConnect(Native Method)
 at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
 at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
 at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
 at java.net.Socket.connect(Socket.java:516)
 at java.net.Socket.connect(Socket.java:466)
 at sun.net.NetworkClient.doConnect(NetworkClient.java:157)
 at sun.net.www.http.HttpClient.openServer(HttpClient.java:365)
 at sun.net.www.http.HttpClient.openServer(HttpClient.java:477)
 at sun.net.www.http.HttpClient.<init>(HttpClient.java:214)
 at sun.net.www.http.HttpClient.New(HttpClient.java:287)
 at sun.net.www.http.HttpClient.New(HttpClient.java:299)
 at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:796)
 at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:748)
 at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:673)
 at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:840)

到網上查了查,應該是資源耗盡了,但是沒有找到解決的方法。
程式片斷程式碼如下:
for (int j = 0; j < 200; j++) {
    long beginTime = System.currentTimeMillis();
    URL url = new URL("...");
    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
    httpURLConnection.setDoOutput(true);
    httpURLConnection.setRequestMethod("POST");
    OutputStream os = httpURLConnection.getOutputStream();
    
    keywordNum = random.nextInt(myKeywords.length);
    
    os.write(("keyword=" + myKeywords[keywordNum]).getBytes("UTF8"));
    os.flush();
    os.close();
    int i = 0;
    int contentLength = 0;
    contentLength = httpURLConnection.getContentLength();
    long endTime = System.currentTimeMillis();
    System.out.println("Thread '" + name + "' search keyword '" + myKeywords[keywordNum] + "' and get content in " + (endTime - beginTime) + " Millis, length=" + contentLength);
   }

後來想了想,既然資源沒釋放,釋放就可以了。查了一下HttpURLConnection有個disconnect方法,但是加上後也沒有用。再找,jdk的docs裡說,HttpURLConnection這個物件關掉相關的InputStream和OutputStream可以釋放掉相關資源,於是試了下,在contentLength = httpURLConnection.getContentLength();這行後面又加了2行:
    InputStream is = httpURLConnection.getInputStream();
    is.close();

問題解決了。
原來只是知道如果不呼叫httpURLConnection的getContentLength或其它get方法,請求是不會提交的,一般如果不需要也不會去調getInputStream,沒想到還有個釋放資源的問題。