5

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;
trincot
  • 317,000
  • 35
  • 244
  • 286
user1324916
  • 49
  • 1
  • 2
  • how does it not work? Do you get an error? – Dan Apr 10 '12 at 19:48
  • 1
    A `ByteArrayOutputStream` writes data to a byte array. After closing the `ByteArrayOutputStream` the byte array is accessible with the `toByteArray` method. Simply closing the `ByteArrayOutputStream` will not make the byte array eligible for garbage collection. – emory Apr 10 '12 at 19:52
  • i works, but the problem is that i have a XML of 80MB and after i save in C: , i'd like to free the heap memory used. – user1324916 Apr 10 '12 at 19:58
  • 1
    That is the job of the garbage collector. Make sure that you do not have extra references to the `ByteArrayOutputStream` hanging around. – emory Apr 10 '12 at 20:08

2 Answers2

12

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.

Tadas S
  • 1,955
  • 19
  • 33
  • the problem is that i should to unzip the file received by FTP and just to get the XML that is in. How can i do that, using what? – user1324916 Apr 10 '12 at 19:59
3

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.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674