Always hit OutOfMemoryError If I try to invoke ejb method with large object as its parameter

Version 1

    Hi, all

        In my stateless EJB, there is on method defined as below.

        public void modelSave(SerializableInputStream model) throws java.rmi.RemoteException;

        The SerializableInputStream is defined as below and its whole definition is attached. The intent of defining such class is that sometimes we need to pass through big object (more than 300M) as parameter to remote ejb instance, and the -Xmx of the JVM is only 512M by default,  to avoid OOM, we didn't want to load the whole object into JVM before invoking ejb method. Meanwhile, we expect JBoss could marshall InputStream object specially, that is not load its content into memory first.

     

       public class SerializableInputStream extends InputStream implements Serializable {

             private InputStream stream;

         ....

         //---------------------------< Serializable >-------------------------------

         private void writeObject(ObjectOutputStream out)

                throws IOException {

            byte[] buffer = new byte[4096];

            int bytes;

            while ((bytes = stream.read(buffer)) >= 0) {

                // Write a segment of the input stream

                if (bytes > 0) {

                    // just to ensure that no 0 is written

                    out.writeInt(bytes);

                    out.write(buffer, 0, bytes);

                }

            }

            // Write the end of stream marker

            out.writeInt(0);

            // close stream

            stream.close();

        }

        private void readObject(ObjectInputStream in)

                throws IOException {

            final File file = File.createTempFile("serializable-stream", "bin");

            OutputStream out = new FileOutputStream(file);

            byte[] buffer = new byte[4096];

            for (int bytes = in.readInt(); bytes > 0; bytes = in.readInt()) {

                if (buffer.length < bytes) {

                    buffer = new byte[bytes];

                }

                in.readFully(buffer, 0, bytes);

                out.write(buffer, 0, bytes);

            }

            out.close();

     

            stream = new FileInputStream(file) {

                private boolean closed = false;

                public void close() throws IOException {

                    super.close();

                    closed = true;

                    file.delete();

                }

                protected void finalize() throws IOException {

                    try {

                        if (!closed) {

                            file.delete();

                        }

                    } finally {

                        super.finalize();

                    }

                }

            };

        }

      }

     

       But from the test result, I can that JBoss marshaller first read its content (the serializable inputstream) into a byte array, which means the big object is loaded into memory. With our default JVM setting, we always hit OOM issue.

      

       Although passing big object with Remote ejb call is not a common use case, please help me if you have any idea. Thanks in advance.

     

     

    Regards,

    -Liang