Tech and Media Labs
This site uses cookies to improve the user experience.


BytesAllocatorAutoDefrag

Jakob Jenkov
Last update: 2019-05-27

The Mem Ops BytesAllocatorAutoDefrag class is capable of allocating smaller sections (blocks) of a bigger byte array. Thus, a single, big byte array can be instantiated, and allocated into smaller sections which can be used as if they were separate byte arrays. You just need to know the start offset of the byte array section you have been allocated, and it's length, and you are good to go.

When you are done using an allocated byte array section you must explicitly free it. When you free a byte array section, the BytesAllocatorAutoDefrag class will automatically defragment its internal big byte array so the freed section is joined with adjacent free sections to form a larger free section from which future sections can be allocated. This is how the BytesAllocatorAutoDefrag is different from the ByteArrayAllocatorManualDefrag .

This short video explains how the allocation, deallocation and defragmentation works:

Create a BytesAllocatorAutoDefrag

To use the BytesAllocatorAutoDefrag class you must first create an instance of it. Here is an example of creating a BytesAllocatorAutoDefrag instance:

BytesAllocatorAutoDefrag allocator = new BytesAllocatorAutoDefrag(new byte[1024 * 1024]);

Notice that you have to pass the underlying byte array as parameter to the BytesAllocatorAutoDefrag. It is this byte array which you can allocate smaller sections (blocks) from. This way you will only ever have this underlying byte array allocated in the JVM. Your memory consumption remains completely stable, and no garbage collection needs to take place.

Allocate a Block

In order to allocate a block (section) of bytes from the underlying byte array, you call the allocate() method. Once allocated, no other allocate() call can allocate the same block until it has been freed. The allocate() method returns the offset into the big, underlying byte array where the allocated block starts. If no block could be allocated, -1 is returned. Here is an example of allocating a block of 1024 bytes:

int offset = allocator.allocate(1024);

Getting a Reference to the Byte Array

You can get a reference to the underlying byte array via the getData() method. Your allocated block will reside at the returned offset inside this byte array. Here is how obtaining the byte array looks:

byte[] data = allocator.getData();

Accessing the Allocated Block

Once you have allocated a block of bytes from the BytesAllocatorAutoDefrag you can access it via the data array, from the offset returned by allocate() and until offset + length - 1. Here is an example of accessing an allocated block of bytes from a BytesAllocatorAutoDefrag:

int blockLength = 1024;
int offset = allocator.allocate(blockLength);
byte[] data = allocator.getData();

data[offset] = 1;                   //first byte of block
data[offset + blockLength -1] = 2;  //last byte of block

Notice the two last lines of the example. These two lines access the first and last byte of the allocated block. You can access all bytes from the first byte to the last byte this way.

Free a Block

Once you are finished with a memory block you must free it again. You free it using the free() method. The free() method takes the start and end offset of the block to free. Here is an example of allocating and freeing a byte block:

int offset = allocator.allocate(1024);

allocator.free(offset, offset + 1024);

Free Part of a Block

The BytesAllocatorAutoDefrag does not care what size of block you free. If you allocate a block of 1024 bytes and write 512 bytes into it, you can free the other 512 bytes immediately. Here is an example of freeing part of an allocated block:

int offset = allocator.allocate(1024);

allocator.free(offset + 512, offset + 1024);

Full BytesAllocatorAutoDefrag Example

Here is a full example showing how to allocate and free a memory block from a Mem Ops BytesAllocatorAutoDefrag :

int offset = allocator.allocate(1024);

byte[] data = allocator.getData();

data[offset] = 1;                   //first byte of block
data[offset + blockLength -1] = 2;  //last byte of block

//do something more with written bytes.

allocator.free(offset, offset + 1024);

Jakob Jenkov




Copyright  Jenkov Aps
Close TOC