本文作为netty内存管理专题的第一篇。
在深究netty内存分配的底层原理之前,先来从外部了解它的基本用法。
1 非池化内存的分配和使用
示例代码如下,以下代码展示了直接内存缓冲的分配、读写和回收:
public static void main(String[] args) throws Exception {
// 获取非池化ByteBuf分配器
ByteBufAllocator alloc = UnpooledByteBufAllocator.DEFAULT;
// 分配一个直接内存缓冲ByteBuf
ByteBuf directBuf = alloc.directBuffer(128);
// 将字节数组写入该ByeBuf
directBuf.writeBytes("这是写到直接内存的字符串".getBytes());
// 将字节缓冲重新读取出来
byte[] bytes = new byte[directBuf.readableBytes()];
directBuf.readBytes(bytes);
System.out.println(new String(bytes));
// 使用完之后,要释放掉
directBuf.release();
}
堆内存缓冲的分配,也是类似,不再啰嗦。我们来看看ByteBufAllocator用于分配内存的API方法:
–ByteBuf buffer(int initialCapacity):用于分配指定大小的ByteBuf,最终分配到的是直接内存还是堆内存,是跟具体实现有关的。
–ByteBuf ioBuffer(int initialCapacity):分配一个适用于IO的ByteBuf,分配出来的通常是直接内存。
–ByteBuf heapBuffer(int initialCapacity):在java堆内存分配一个ByteBuf。
–ByteBuf directBuffer(int initialCapacity):在直接内存分配一个ByteBuf。
这里先了解这些API的含义,这些方法的实现,在后续的文章中再具体讲解。
2 内存池的内存分配
内存池的内存分配,也是通过分配器来分配,分配示例如下。由于读写和非内存池的ByteBuf一样,所以省略读写代码的示例:
public static void main(String[] args) throws Exception {
// 获取内存池分配器
ByteBufAllocator pooledAlloc = PooledByteBufAllocator.DEFAULT;
// 分配正常大小的ByteBuf
ByteBuf pooledBuf = pooledAlloc.heapBuffer(9000);
ByteBuf pooledBuf2 = pooledAlloc.heapBuffer(8192);
// 分配小内存块
ByteBuf tinyBuf = pooledAlloc.heapBuffer(256);
ByteBuf tinyBuf2 = pooledAlloc.heapBuffer(256);
}
基本使用示例结束。