Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the best way to close a ByteArrayOutputStream?

I need to optimize a application that uses too much heap memory. I'm having problem in close a ByteArrayOutputStream variable after using the same. I've tried to do using close() but it does not work. this is the code:

ByteArrayOutputStream zipOutTempStream = new ByteArrayOutputStream();
//arquivo.getZipStream() has the XML received by FTP.
//STreamEtils is the function who transfers the XML to zipOutTempStream
StreamUtils.copiarStream(arquivo.getZipStream(), zipOutTempStream);

            //Creating a new XML to write over this.
            File arquivo1 = new File("C:/XML.xml");
            if (arquivo1.exists()) {
                System.out.println("ele existe");
            } else {
                if (arquivo1.createNewFile()) {
                    System.out.println("arquivo criado");
                } else {
                    System.out.println("arquivo não criado");
                }
            }

            FileOutputStream arquivo2 = new FileOutputStream(arquivo1);
            //Copy the unziped XML to the new xml created.
            StreamUtils.copiarStream(StreamUtils                .uncompressXmlFromZipStream(new ByteArrayInputStream(zipOutTempStream.toByteArray())), arquivo2);
            arquivo.setZipStream(null);
            arquivo.setXmlStream(null)      
return arquivo;
like image 772
user1324916 Avatar asked Dec 13 '22 03:12

user1324916


2 Answers

You cannot close a ByteArrayOutputStream, since it's close() method is documented as

Closing a ByteArrayOutputStream has no effect. The methods in this class can be called after the stream has been closed without generating an IOException.

This output stream is backed by an array; it is NOT a buffered stream. If you feel it is using too much memory, you should output bytes directly to some endpoint, such as a file or a socket, using an appropriate OutputStream.

like image 156
afk5min Avatar answered Dec 14 '22 17:12

afk5min


I think you are carelessly using too much memory. close() has nothing to do with it. In fact there is no need for closing ByteArrayOutputStream. Here you are copying the ZIP file into wrapped byte[] array:

ByteArrayOutputStream zipOutTempStream = new ByteArrayOutputStream();
StreamUtils.copiarStream(arquivo.getZipStream(), zipOutTempStream);

and few lines later you convert the byte[] array back to InputStream:

StreamUtils.copiarStream(StreamUtils.uncompressXmlFromZipStream(
  new ByteArrayInputStream(zipOutTempStream.toByteArray())
), arquivo2);

Seems like this generated byte[] array is pretty huge (confirm with logging). Instead of storing the whole ZIP file in memory (in byte[]) store in a temporary file and read it back.

like image 22
Tomasz Nurkiewicz Avatar answered Dec 14 '22 15:12

Tomasz Nurkiewicz