Приложение Java с URLConnection приводит "Слишком много открытых файлов" - PullRequest
4 голосов
/ 11 ноября 2011

Я написал небольшие фрагменты 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();
    }
}
}

Когда я написал другую программу для вызова метода в этом классе, что приведет к «Слишком много открытых файлов», а затем ОС откажетсяпользователь для входа.Вызванный сценарий выглядит следующим образом:

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

Количество дескрипторов (пул событий сокета канала) будет достигать тысяч.

Я пробовал много методов, чтобыизбежать этого, но не удалось.Кто-нибудь может сказать мне дефект в вышеупомянутой программе?

Ответы [ 2 ]

4 голосов
/ 11 ноября 2011

Вы не закрываете читатель ввода.Он должен быть закрыт.

Как правило, вы должны закрывать ресурсы в блоке finally.

В этом случае вы должны закрыть входные и выходные считыватели в finallyблок.

1 голос
/ 05 августа 2014

Если вы не нашли решение, стоит проверить эту ветку:

Android - HttpUrlConnection не закрывается. В конечном итоге приводит к SocketException

Это как-то связано с "Keep-Alive" соединениями в Jellybean. Надеюсь, это поможет

...