-
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分配緩衝區。
最後附上一張類圖: