BytesAllocatorAutoDefrag

时间:2020-01-09 10:36:57  来源:igfitidea点击:

Mem Ops BytesAllocatorAutoDefrag类能够分配较大字节数组的较小部分(块)。因此,可以实例化一个大字节数组,并将其分配给较小的部分,就可以将它们当作单独的字节数组使用。我们只需要知道已分配的字节数组部分的起始偏移量及其长度,就可以了。

使用分配的字节数组部分完成操作后,必须显式释放它。当我们释放字节数组部分时,BytesAllocatorAutoDefrag类将自动对其内部的大字节数组进行碎片整理,以便将释放的部分与相邻的空闲部分结合在一起以形成更大的空闲部分,从中可以分配将来的部分。这就是BytesAllocatorAutoDefrag与ByteArrayAllocatorManualDefrag的不同之处。

创建一个BytesAllocatorAutoDefrag

要使用BytesAllocatorAutoDefrag类,我们必须首先创建一个实例。这是创建BytesAllocatorAutoDefrag实例的示例:

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

注意,我们必须将底层字节数组作为参数传递给BytesAllocatorAutoDefrag。我们可以从该字节数组中分配较小的部分(块)。这样,我们将仅在JVM中分配此基础字节数组。内存消耗保持完全稳定,并且不需要进行垃圾收集。

分配块

为了从底层字节数组中分配字节的一个块(部分),请调用allocate()方法。一旦分配完,其他的" allocate()"调用就无法分配相同的块,直到它被释放为止。 allocate()方法将偏移量返回到大的底层字节数组中,在该数组中已分配的块开始。如果无法分配任何块,则返回-1. 这是分配1024个字节的块的示例:

int offset = allocator.allocate(1024);

获取对字节数组的引用

我们可以通过getData()方法获取对底层字节数组的引用。我们分配的块将驻留在此字节数组内返回的偏移量处。这是获取字节数组的样子:

byte[] data = allocator.getData();

访问分配的块

一旦从" BytesAllocatorAutoDefrag"中分配了一个字节块,就可以通过数据数组访问它,从" allocate()"返回的偏移量开始,直到" offset + length 1"。这是一个从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

注意示例的最后两行。这两行访问分配的块的第一个和最后一个字节。我们可以通过这种方式访问从第一个字节到最后一个字节的所有字节。

释放一块

完成存储块后,必须再次释放它。我们可以使用free()方法释放它。 free()方法将块的开始和结束偏移量释放。这是分配和释放字节块的示例:

int offset = allocator.allocate(1024);

allocator.free(offset, offset + 1024);

块的空闲部分

BytesAllocatorAutoDefrag并不关心我们释放的块大小。如果分配一个1024字节的块并向其中写入512字节,则可以立即释放其他512字节。这是释放分配的块的一部分的示例:

int offset = allocator.allocate(1024);

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

Full BytesAllocatorAutoDefrag示例

这是一个完整的示例,显示了如何从Mem OpsBytesAllocatorAutoDefrag分配和释放内存块:

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);