Java app with URLConnection leads “Too many open f

2019-06-24 03:41发布

问题:

I wrote a small pieces of java program as following:

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

When I wrote another program to invoke method in this class, which will lead "Too many open files" and then the OS will refuse user to login. The called script is as following:

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

When the problem reappeared, I found that the handle occupation was increasing. The following is piece of message that I execute the command "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

Number of handles (pipe socket eventpool) will up to thousands.

I tried many methods to avoid this, but failed. Anybody can tell me the defect in the above program?

回答1:

You do not close the input reader. It should be closed.

As a general rule, you should close resources in a finally block.

In this case, you should close the input and output readers in a finally block.



回答2:

If you haven't found a solution, worth checking this thread out:

Android - HttpUrlConnection is not closing. Eventually results to SocketException

This is something to do with "Keep-Alive" connections in Jellybean. Hope that helps