简体   繁体   中英

Java DataOutputStream / DataInputStream OutOfMemoryError

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?

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM