background image

左边五颜六色的
是不同的

region

在内存中的位置,
它是无序的,因
为客户端的请求
是无规律的。此
时 假 设 黄 色 的
region 触 发 了
flush,那么右边
将会出现与之对
应的多个空洞,
即内存碎片。这
张图以

region 为

粒度,仅仅是为
了更直观地表示
这种现象。真实
场景中,这些空
洞是更细粒度的

KeyValue 级对象,它能直接导致创建对象时触发 Full GC。

Arena Allocation

Arena Allocation 是一种非传统的内存管理方法。它通过顺序化分配内存,内存数据分块等特性使内存碎片粗
化,有效改善了内存碎片导致的

Full GC 问题。

它的原理:

3 创建一个大小固定的 bytes 数组和一个偏移量,默认值为 0。
4 分配对象时,将新对象的 data bytes 复制到数组中,数组的起始位置是偏移量,复制完成后为偏移
量自增

data.length 的长度,这样做是防止下次复制数据时不会覆盖掉老数据(append)。

5 当一个数组被充满时,创建一个新的数组。
6 清理时,只需要释放掉这些数组,即可得到固定的大块连续内存。

Arena Allocation 方案中,数组的大小影响空间连续性,越大内存连续性越好,但内存平均利用率会降低。

HBase 的解决方案-MSLAB

MSLAB,全称是 MemStore-Local Allocation Buffer,是 Cloudera 在 HBase 0.90.1 时提交的一个 patch 里包含
的特性。它基于

Arena Allocation 解决了 HBase 因 Region flush 导致的内存碎片问题。

MSLAB 的实现原理(对照 Arena Allocation,HBase 实现细节):

7 MemstoreLAB 为 Memstore 提供 Allocator。
8 创建一个 2M(默认)的 Chunk 数组和一个 chunk 偏移量,默认值为 0。
9 当 Memstore 有新的 KeyValue 被插入时,通过 KeyValue.getBuffer()取得 data bytes 数组。将 data 复制