0

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?

  • You're thrashing the garbage collector. Other than that I can't see any obvious reason for that behavior. Exactly how long does it take and what version of Java and which platform are you testing? – Elliott Frisch May 07 '20 at 18:22
  • Dear @ElliottFrisch I'm using java version 10.0.1 on lubuntu 16.4. – Hedayat Mahdipour May 07 '20 at 18:48
  • Which Java 10? And Java 10 is no longer supported (by Oracle). In fact, it was only around for about 6 months before Java 11 was released. You should consider upgrading. Java 11 is a Long Term Support release. As was Java 8. – Elliott Frisch May 07 '20 at 19:35

0 Answers0