On Android 4.4.4, how to deal with garbage collector when a lot of byte array are created?

273 Views Asked by At

I am currently stuck on this point, I am using engine.io java client and I have to get binary data from the server, actually moreover than 40000 bytes as a byte array every 16ms.

It works well, I can get the data without probleme, however, when the data is parsed through the methods, a new byte array is created each time I received the data, every 16ms.

Watching the monitor, I can see that each time new byte is called to store the data, the Dalvik runtime allocates the same amount of memory, and thus the garbage collector is activated a lot of time and freezes at some point in the application.

Is 16ms is too fast for the garbage collector to clear all the unused byte arrays ? Is there a recommended size when using the byte array in android ?

edit: here is the code

on my main activity, I have a handler like this when a message from the websocket arrives :

@Override
public void onMessage(ByteBuffer buffer) {     
    System.out.println("received message: " + buffer);
    if (buffer.hasArray()) {
        byte[] array = buffer.array();
    }
}

And before, it is parsed by this code :

   public static class InputStreamImpl extends DataInputStream {
        public InputStreamImpl(InputStream in) {
            super(in);
        }

        public byte[] readBytes(int length) throws IOException {
            byte[] buffer = new byte[length];
            readFully(buffer);
            return buffer;
        }
    }

Length is the size of the current byte array coming from the server. In Monitor, I can see that the line new byte[length] increases the heap memory.

Should I put a very large fixed array buffer and reuse the same one ?

Thank you !

1

There are 1 best solutions below

0
On BEST ANSWER

Generally speaking, the garbage collector will run when enough garbage has accumulated. How much time it consumes depends roughly on how many total objects there are on the heap. A byte[40000] is a medium-sized object, but 60 per second adds up to 2.4 MB/s, or nearly 150 MB/min. That's pretty substantial for a small device such as you would expect to find running Android (and also pretty substantial for your data plan, if you're actually receiving data at that rate).

As a general principle, you should size your buffer appropriately for the amount of data you need or realistically expect to receive per I/O transaction. Having done that, you want to reuse that buffer and avoid unnecessarily copying it. Those are both generally possible. You present no code, so I cannot begin to guess why your buffer is being copied.