Чтение Входа и Потоков сообщений об ошибках Одновременно с помощью BufferedReaders Зависает

Нет никакого реального опасность в не освобождении Ваших переменных, но если Вы присваиваете указатель на блок памяти к другому блоку памяти, не освобождая первый блок, первый блок больше не доступен, но все еще занимает место. Это - то, что назвало утечку памяти, и если Вы сделаете это с регулярностью тогда, то Ваш процесс начнет использовать все больше памяти, устраняя системные ресурсы из других процессов.

, Если процесс является недолгим, можно часто сходить с рук выполнение этого, поскольку вся выделенная память исправлена операционной системой, когда процесс завершается, но я советовал бы привыкать освобождать всю память, для которой у Вас нет дальнейшего использования.

5
задан akarnokd 28 August 2009 в 22:20
поделиться

4 ответа

http://bugs.sun.com/bugdatabase /view_bug.do?bug_id=4090471

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

5
ответ дан 18 December 2019 в 08:29
поделиться

Есть еще две возможности:

  • Использовать ProcessBuilder и вызовите redirectErrorStream (true) , чтобы объединить два потока, и вам нужно прочитать один поток. У меня есть пример здесь .
  • В JDK7 вы можете вызвать inheritIO () для автоматической пересылки всего.

Править На второй взгляд кажется, что ready () вводит в заблуждение вашу программу. Попробуйте следующее:

private void forwardStreamtoStd(InputStream in, InputStream err) 
throws IOException {
    int c = -1;
    BufferedReader inReader = new BufferedReader(
        new InputStreamReader(in, "US-ASCII"));
    BufferedReader errReader = new BufferedReader(
        new InputStreamReader(err, "US-ASCII"));
    boolean inFinished = false, errFinished = false;

    try {
        System.out.println("Begin stream read loop...");
        if (!inFinished) {
            while ((c = inReader.read()) != -1) {
                    System.out.print((char) c);
            }
            inFinished = true;
        }

        if (!errFinished) {
            while ((c = errReader.read()) != -1) {
                System.err.print((char) c);
            }
            errFinished = true;
        }
        System.out.println("End stream read loop.");
    } 
    catch (IOException e) {
        throw e;
    } 
    finally {
        errReader.close();
        inReader.close();
    }
}

Или еще лучше, не используйте BufferedReader, если не планируете никаких дополнительных преобразований:

private void createReader(final InputStream in, final OutputStream out) {
    new Thread() {
        public void run() {
            try {
                int c = 0;
                while ((c = in.read()) != -1) {
                    out.write(c);
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                in.close();
            }
        }
    }.start();
}
private void forwardStreamtoStd(InputStream in, InputStream err) 
throws IOException {
    createReader(in, System.out);
    createReader(err, System.err);
}
10
ответ дан 18 December 2019 в 08:29
поделиться

Если я правильно помню, порожденный процесс никогда не закроет поток - поэтому вам нужно будет иметь читателей в их собственных потоках, спать в основном потоке, пока процесс не будет завершен, а затем закрыть читателей.

1
ответ дан 18 December 2019 в 08:29
поделиться

Это существенно , чтобы использовать 2 потока одновременно, чтобы предотвратить блокировку. См. эту статью для получения дополнительной информации, и, в частности, обратите внимание на механизм StreamGobbler , который захватывает stdout / err в отдельных потоках.

3
ответ дан 18 December 2019 в 08:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: