使用HttpURLConnection時遇到的資源未釋放的問題
阿新 • • 發佈:2019-01-04
今天自己寫了一個壓力測試的小程式,同時啟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,沒想到還有個釋放資源的問題。