URLConnection的Java应用程序导致“打开的文件过多”

我写了一小段java程序如下:

package com.ny.utils.pub; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class NetWriter { private static String link = "http://xxx.yyyyyy.com:4444"; public String getLink() { return link; } public static void setLink(String link) { NetWriter.link = link; } private static HttpURLConnection conn = null; private static BufferedReader bufReader = null; private static InputStreamReader isReader = null; private static OutputStreamWriter osw = null; private static URL url = null; static { try { url = new URL(link); } catch(MalformedURLException e) { } } public static void write(String msg) { long threadId = Thread.currentThread().getId(); System.out.println("--Insert>{" + threadId + "}:" + msg); try { conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Language", "en-US"); conn.setUseCaches(false); conn.setDoOutput(true); conn.setReadTimeout(5000); conn.setConnectTimeout(5000); osw = new OutputStreamWriter(conn.getOutputStream()); osw.write(msg); osw.flush(); osw.close(); if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) { System.err.println("Server not return HTTP_OK status"); } else { System.out.println(" request: " + msg); isReader = new InputStreamReader(conn.getInputStream()); bufReader = new BufferedReader(isReader); String rep = bufReader.readLine(); if (conn.getResponseCode() == 200) { System.out.println("Post data OK to " + link); } System.out.println(" response: " + rep); } } catch(IOException e) { System.err.println("Post data error: " + link + " " + e.getMessage()); e.printStackTrace(); } } } 

当我编写另一个程序调用这个类的方法时,会导致“打开的文件太多”,然后操作系统拒绝用户login。 被调用的脚本如下所示:

 try{ NetWriter.write(new String(content, "utf-8")); }catch(Exception e){ logger.error(e.getMessage()); e.printStackTrace(); } } 

当问题再次出现时,我发现处理职位正在增加。 以下是我执行命令“lsof -p PROGRAM_PID”的消息

 java 27439 root 66u unix 0xffff8103473fb6c0 10151765 socket java 27439 root 67u unix 0xffff8103473fb6c0 10151765 socket java 27439 root 68u unix 0xffff8103473fb6c0 10151765 socket java 27439 root 69r FIFO 0,6 10151917 pipe java 27439 root 70w FIFO 0,6 10151917 pipe java 27439 root 71r 0000 0,11 0 10151918 eventpoll java 27439 root 72r FIFO 0,6 10151919 pipe java 27439 root 73w FIFO 0,6 10151919 pipe java 27439 root 74r 0000 0,11 0 10151920 eventpoll java 27439 root 75u unix 0xffff8103473fb6c0 10151765 socket java 27439 root 76u unix 0xffff8103473fb6c0 10151765 socket java 27439 root 77r FIFO 0,6 10152042 pipe java 27439 root 78w FIFO 0,6 10152042 pipe java 27439 root 79r 0000 0,11 0 10152043 eventpoll java 27439 root 80r FIFO 0,6 10152044 pipe java 27439 root 81w FIFO 0,6 10152044 pipe java 27439 root 82r 0000 0,11 0 10152045 eventpoll java 27439 root 83u unix 0xffff8103473fb6c0 10151765 socket java 27439 root 84r FIFO 0,6 10154168 pipe java 27439 root 85w FIFO 0,6 10154168 pipe java 27439 root 86r 0000 0,11 0 10154169 eventpoll java 27439 root 87r FIFO 0,6 10154170 pipe 

句柄数量(pipe道sockets事件池)将高达数千个。

我尝试了很多方法来避免这种情况,但是失败了。 有人可以告诉我上述程序的缺陷吗?

您不要关闭输入阅读器。 它应该被关闭。

一般来说,你应该关闭finally块中的资源。

在这种情况下,您应该关闭finally块中的输入和输出读取器。

如果你还没有找到解决办法,值得检查这个线程:

Android – HttpUrlConnection不关闭。 最终结果为SocketException

这与Jellybean中的“Keep-Alive”连接有关。 希望有所帮助