1

I'm trying to send a byte array containing 16 items over sockets using DataOutputStream on the client and DataInputStream on the server.

These are the methods I am using for sending/receiving.

public void sendBytes(byte[] myByteArray) throws IOException {
    sendBytes(myByteArray, 0, myByteArray.length);
}

public void sendBytes(byte[] myByteArray, int start, int len) throws IOException {
    if (len < 0)
        throw new IllegalArgumentException("Negative length not allowed");
    if (start < 0 || start >= myByteArray.length)
        throw new IndexOutOfBoundsException("Out of bounds: " + start);     
    dOutput.writeInt(len);
    if (len > 0) {
        dOutput.write(myByteArray, start, len);
        dOutput.flush();
    }       
}

public byte[] readBytes() throws IOException {
    int len = dInput.readInt();
    System.out.println("Byte array length: " + len); //prints '16'
    byte[] data = new byte[len];
    if (len > 0) {
        dInput.readFully(data);
    }
    return data;
}

It all works fine, and I can print the byte array length, byte array (ciphertext), and then decrypt the byte array and print out the original plaintext I sent, but immediately after it prints in the console, the program crashes with a OutOfMemoryError: Java heap space.

I have read this is usually because of not flushing the DataOutputStream, but I am calling it inside the sendBytes method so it should clear it after every array is sent.

The compiler is telling me the error is occuring inside readBytes on the line byte[] data = new byte[len]; and also where I call readBytes() in the main method.

Any help will be greatly appreciated!

Edit

I am actually getting some unexpected results.

17:50:14 Server waiting for Clients on port 1500. Thread trying to create Object Input/Output Streams 17:50:16 Client[0.7757499147242042] just connected. 17:50:16 Server waiting for Clients on port 1500. Byte array length: 16 Server recieved ciphertext: 27 10 -49 -83 127 127 84 -81 48 -85 -57 -38 -13 -126 -88 6 Server decrypted ciphertext to: asd 17:50:19 Client[0.7757499147242042] Byte array length: 1946157921

I am calling readBytes() in a while loop, so the server will be listening for anything being transmitted over the socket. I guess its trying to run it a second time even though nothing else has been sent and the len variable is somehow being set to 1946157921. What logic could be behind this?

pjmil
  • 1,977
  • 7
  • 23
  • 40

3 Answers3

3

You must be sending something else over the socket; not reading it the same way you wrote it; and so getting out of sync. The effect will be that you're reading a length it that isn't a real length; is too big; and runs out of memory when you try to allocate it. The fault isn't in this code. Except of course that if len == 0 you shouldn't allocate the bye array when reading.

I have read this is usually because of not flushing the DataOutputStream

It isn't.

len variable is somehow being set to 1946157921.

Exactly as predicted. QED

user207421
  • 289,834
  • 37
  • 266
  • 440
  • You're right. I was sending an object over the socket also in a different method. I did not know using both ObjectOutputStreams and DataOutputStreams would cause issues reading/writing in the socket. – pjmil May 31 '14 at 08:33
  • 1
    It doesn't need to, but use of multiple streams per socket is fraught with difficulties and best avoided. – user207421 May 31 '14 at 09:51
0

You are running out of the available heap. Quick solution for this would be increasing (or specifying is missing) the -Xmx parameter in your JVM startup parameters to the level where the application is able to complete the task at hand.

Flexo
  • 82,006
  • 22
  • 174
  • 256
Ivo
  • 404
  • 3
  • 7
-1

Run your application with -Xms1500m in console, in Netbeans you can find it in project properties->Run->VM options.

I faced this out of memory problem today and after tweaking sometime with Xms I was able to fix the problem. Check if it work with you, if there is something really bigger then this than you will have to check how you can improve your code.

Check discussion here

Community
  • 1
  • 1
Raj
  • 922
  • 1
  • 7
  • 12
  • I'll try it now. What exactly does this do? – pjmil May 31 '14 at 07:46
  • You mean to suggesting setting `Xmx` which increases the max heap space. – Tim Bender May 31 '14 at 07:53
  • By this way you are configuring JVM memory uses, you can try -Xmx also and try to increase the size. I think, not sure, in win32 you can use upto 2GB. – Raj May 31 '14 at 07:56
  • @TimBender at least it worked for me today. I was facing problem with ArrayList where I was adding snapshot taken by Java Robot. – Raj May 31 '14 at 07:57
  • @Raj See: http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html Perhaps Netbeans is being nice to you and setting Xmx for you, but generally, Xms (min size) can not exceed Xmx (max size). – Tim Bender Jun 02 '14 at 06:14
  • @TimBender, Sorry for not mentioning -Xmx. We can keep both equal. Xms The size it claim at start up and Xmx the maximum size, which I think, theoretically, can be upto 4GB in 32 bit window system. – Raj Jun 02 '14 at 06:50