Проводя эксперимент с 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 для сборки мусора, поскольку его больше нет в конвейере потока, и на него больше нет ссылок. Что не так с этой программой? Что мне не хватает, что приводит к неограниченному потреблению памяти?