While doing an experiment on Java piped streams and object streams, I found something unusual. Consider the following code. In this code I've created a piped stream using a PipedOutputStream
which is connected to a PipedInputStream
that are wrapped inside an ObjectOutputStream
and an ObjectInputStream
respectively. Then I used the output terminal to send very large amounts of data, and receive the data back from the input terminal.
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
The problem is that memory consumption of the program increases continually, until I get an OutOfMemoryError
. When I retrieve an object from the input terminal, I expect that it will go for garbage collection, since It's not in the stream pipe anymore, and there is no more references pointing to it. What's wrong with this program? What am I missing that causes unlimited memory consumption?