-
PageSource
页源,负责页分配,默认是的实现是:UpfrontAllocatingPageSource-预交付的page源。
重要属性:
-
List buffers = new ArrayList<>();
存放分配好的内存块(chunk),最大1G。
-
List<PowerOfTwoAllocator> sliceAllocators = new ArrayList<>();
页内存分配器,每个内存块对应单独的一个页内存分配器。
-
List<PowerOfTwoAllocator> victimAllocators = new ArrayList<>();
祭品页内存分配器,内存使用完毕时,如果可以从祭品内存中分配,采用此分配器,每个内存块对应单独的一个祭品页内存分配器。
-
List<NavigableSet> victims = new ArrayList<>();
可以作为祭品的页内存。
重要方法:
-
初始化方法
初始化时会参照
HeuristicConfiguration
的maximumChunkSize调用BufferSource进行内存分块,如果maximumSize低于1G,只分成一块(chunk);否则,会按照每块最大1G来分块。分配好的块为ByteBuffer,存放在属性为buffers列表中。
-
Page allocate(int size, boolean thief, boolean victim, OffHeapStorageArea owner)
努力分配一个大小为size的页。
thief:分配时是否可以从祭品中偷空间。
victim:分配的页是否可以被标记为祭品。
-
void free(Page page)
释放某一页
-
-
PowerOfTwoAllocator
用于从内存块中分配内存页,其实现借助于AA树(红黑树的变种)。
-
OffHeapStorageArea
一、重要属性:
-
int initialPageSize
初始pageSize,来自于HeuristicConfiguration.getSegmentDataPageSize(),页内存的大小。
-
int maximalPageSize
最大pageSzie,默认同initialPageSize。
-
int pageGrowthAreaSize
其值为:maximalPageSize - initialPageSize。
-
float compressThreshold:默认为0。
-
boolean thief; boolean victim;
上述两个参数是一对,含义是如果分配的页可以被标记为祭品,那么为了满足分配的需求,就可以从祭品页中偷取内存,用于PageSource中。
-
PageSource pageSource:参见PageSource。
-
Allocator allocator:参见Allocator。
-
Map<Integer, Page> pages = new ConcurrentHashMap<>(1, 0.75f, 1);
存放分配的页,key是pages.size()。
二、重要方法:
-
long allocate(long size)
采用Allocator分配大小为size的内存,并返回内存起始地址。分配失败尝试调用expandData()扩展内存。
-
boolean expandData()
调用PageSource.allocate(thief为false,victim为true)进行页分配,并存储在pages属性中,实际调用Allocator.expand(maximalPageSize)进行内存扩展。
-
int pageIndexFor(long address)
根据给的内存地址,定位页(存储在pages中)的索引。
-
int pageSizeFor(int index)
查询某个页的大小。
-
long addressForPage(int index)
查询某个页的起始地址。
-
int pageAddressFor(long address)
查询某个地址在页上的地址(每个页的地址都从0开始)。
-
void writeInt(long address, int value)
根据address定位到page,写入value值。
-
void writeBuffer(long address, ByteBuffer data)
根据address定位到page,写入data值。
-
-
Allocator
采用Doug Lea大神的内存分配器:dlmalloc进行内存管理。
默认实现是:IntegerBestFitAllocator,包含如下重要方法:
- long allocate(long size):分配内存。
- void free(long address):释放内存。
- void expand(long size):扩展内存。
其持有OffHeapStorageArea做实际的存储。
-
HeuristicConfiguration
启发式配置,其为很多关键类初始化提供了参数。
重要属性:
- idealMaxSegmentSize:map中理想的最大段尺寸,用于并发设置,默认为32M。
- minimumSegmentCount :map中的最小段数,用于并发设置,默认为16。
- maximumSegmentCount :map中的最大段数,用于并发设置,默认为16384。
- maximumChunkSize:内存划分块最大尺寸,大小默认为1G。
- maximalSegmentSizeRatio:默认为4。
- initialSegmentSizeRatio:hash表大小,默认为16。
- assumedKeyValueSize:预估的key和value大小,默认为1024。
重要方法不再介绍,举几个例子,如果设置maximumSize为10M,那么关键参数如下:
Maximum Size (specified) : 10.0MB // offheap初始化大小 Minimum Chunk Size : 2.5MB // offheap切分为内存块的最小大小 Maximum Chunk Size : 10.0MB // offheap切分为内存块的最大大小 Concurrency : 16 // 并发量,也是Segment(OffHeapHashMap)实例数 Initial Segment Table Size : 32 slots // Segment(OffHeapHashMap)的hash表大小 Segment Data Page Size : 32KB // 内存页大小
如果设置maximumSize为5G,那么关键参数如下:
Maximum Size (specified) : 5.0GB Minimum Chunk Size : 160.0MB Maximum Chunk Size : 1GB Concurrency : 128 Initial Segment Table Size : 2K slots Segment Data Page Size : 2MB
如果设置maximumSize为10G,那么关键参数如下:
Maximum Size (specified) : 10.0GB Minimum Chunk Size : 160.0MB Maximum Chunk Size : 1GB Concurrency : 256 Initial Segment Table Size : 2K slots Segment Data Page Size : 2MB
-
Page
内存页
重要属性:
-
ByteBuffer buffer;
堆外内存。
-
OffHeapStorageArea binding;
用于内存释放。
-
int index;
此页在哪个内存块上。
-
int address;
此页在内块上的起始地址
-
boolean freeable;
是否空闲
-
-
BufferSource
缓冲区源,offheap对应的实现为OffHeapBufferSource,其可以直接分配堆外内存。
重要方法:
ByteBuffer allocateBuffer(int size):根据给的size分配缓冲区。
最后附上一张类图: