1

I am experiencing a memory problem that I do not understand. I have the following case

Case 1

public  byte[] getBytes(InputStream is) throws IOException {

            int len;
            int size = 1024;
            byte[] buf;

              ByteArrayOutputStream bos = new ByteArrayOutputStream();
              buf = new byte[size];
              while ((len = is.read(buf, 0, size)) != -1)
              {
                bos.write(buf, 0, len);
              }
              buf = bos.toByteArray();

            return buf;
          }

Public void dosomething()
{
 //instructions
InputStream is = new ByteArrayInputStream(getBytes(bodyPart.getInputStream()));

}

Work fine without error

but this

Case 2

Public void dosomething()
{
 //instructions
ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    int len;
                    int size = 1024;
                    byte[] bufferFichierEntree = new byte[size];
                     while ((len = bodyPart.getInputStream().read(bufferFichierEntree, 0, size)) != -1)
                     {
                         bos.write(bufferFichierEntree, 0, len);
                     }
InputStream is = new ByteArrayInputStream(bufferFichierEntree);

}

return a java.lang.OutOfMemoryError: Java heap space and a don t know why ? The only difference is that in the first case i use a function unlike the second case

3
  • Have you tried creating a variable to hold the input stream outside the while? Ie. "InputStream is = bodyPart.getInputStream();" then in the while loop do "while ((len = is.read(bufferFichierEntree, 0, size)) > 0)". Commented Jul 11, 2012 at 15:49
  • Your main problem is that the code is poorly organized. In addition you do not show us the implementation of your getInputStream to know what it's doing. Commented Jul 11, 2012 at 16:00
  • @Hot Licks Thank you for your help . Yeah i am sorry for the clarity of my code , but my program is very long so i take only the essential parts. The getInputStream method comes from the Part class(java mail api) and not from me Commented Jul 11, 2012 at 16:13

3 Answers 3

4

In

while ((len=bodyPart.getInputStream().read(bufferFichierEntree, 0, size)) != -1) 

you are creating new InputStream in each loop, so you are reading only first bytes in each loop.

Try to create input stream before while and use it the way you did in your first example.

Sign up to request clarification or add additional context in comments.

Comments

1

The reason for it might be:

When you are using two methods, the ByteArrayOutputStream goes out of scope and can be cleaned up by the Garbage Collector (GC).

Using only one method, you the buffer can't be cleaned up by GC since it is still in the scope, unless you nullify it.

Of course, the other reason might be that you are creating each time a new InputStream inside your loop, since we don't know exactly what bodyPart.getInputStream() does. If this is the case, solve it like this:

InputStream in = bodyPart.getInputStream();
while ((len = in.read(bufferFichierEntree, 0, size)) != -1)
{
    bos.write(bufferFichierEntree, 0, len);
}

3 Comments

@HotLicks: Think again, it isn't. If the buffer gets really large, this can be the problem.
Well, I'll give him the benefit of the doubt. The main problem is that the code is poorly organized and several critical pieces are not shown.
@Martijn Courteaux Thank you for your help . It was indeed the fact that i create a new inputstream in my loop
1

seems like a scoping problem with the getInputStream, in the first example you are using 1 InputStream, in the second one infinity,and reading the first 1000 bytes every time. if you change it to like;

InputStream is = bodyPart.getInputStream(); 
while ((len = is.read(bufferFichierEntree, 0, size)) != -1) {

it should run as expected.

1 Comment

No problem, streams are cause of common mistakes:D

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.