OutOfMemoryError при отправке и получении больших объемов данных с использованием конвейерных потоков - PullRequest
0 голосов
/ 07 мая 2020

Проводя эксперимент с Java конвейерными потоками и объектными потоками, я обнаружил кое-что необычное. Рассмотрим следующий код. В этом коде я создал конвейерный поток, используя PipedOutputStream, который подключен к PipedInputStream, заключенным внутри ObjectOutputStream и ObjectInputStream соответственно. Затем я использовал выходной терминал для отправки очень больших объемов данных и получения данных обратно с входного терминала.

import java.io.*;
import java.util.Random;

public class PipedStreamsTest {
    public static void main(String[] args) {
        final PipedInputStream inputRaw = new PipedInputStream();
        Thread newThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    PipedOutputStream outputRaw = new PipedOutputStream();
                    outputRaw.connect(inputRaw);
                    ObjectOutputStream output = new ObjectOutputStream(outputRaw);

                    for(long i = 0; i < 1_000_000_000_000L; i++) {
                        output.writeObject(getRandomIntArray());
                    }
                    output.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                } // end of try-catch block
            } // end of method run
        }); // end of newThread initialization
        newThread.start();

        ObjectInputStream input;
        try {
            input = new ObjectInputStream(inputRaw);
            while(true) {
                input.readObject();
            }
        } catch(EOFException e) {
            System.out.println("End of stream");
            System.exit(0);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } // end of try-catch block
    } // end of method main

    private static int[] getRandomIntArray() {
        Random rand = new Random();
        int[] result = new int[10];
        for(int i = 0; i < result.length; i++)
            result[i] = rand.nextInt(100);
        return result;
    } // end of method getRandomIntArray()
} // end of class

Проблема в том, что потребление памяти программой постоянно увеличивается, пока я не получу OutOfMemoryError. Когда я извлекаю объект из входного терминала, я ожидаю, что он будет go для сборки мусора, поскольку его больше нет в конвейере потока, и на него больше нет ссылок. Что не так с этой программой? Что мне не хватает, что приводит к неограниченному потреблению памяти?

...