Arena Allocation 如何才能避免 HBase 触发 Full GC
Arena Allocation,是一种 GC 优化技术,它可以有效地减少因内存碎片导致的 Full GC,从而提高系统的整
体性能。本文介绍
Arena Allocation 的原理及其在 Hbase 中的应用-MSLAB。
背景
假设有
1G 内存,我顺序创建了 1 百万个对象,每个对象大小 1K,Heap 会被渐渐充满且每个对象以创建顺
序相邻。此时,如果我释放
50 万个奇数对象,即 1 3 5 7 后,剩余空间会多出 500M,而这段内存空间就不再
连续了。问题出现?
如果我打算
new 一个 2K 大小的对象,JVM 将无从分配它,因为找不到连续可用的内存空间来容纳这个对象,
就算
Heap 当时还有 500M 的剩余空间,也无能为力。最终,JVM 会选择触发 Full GC 重新压缩内存使之连续
然后再分配。
结论:触发
Full GC,并不只有在内存满或达到触发比例的时候,还有可能是因为内存碎片。
产生内存碎片的主要原因是:
1 分配的大小不一。
2 分配的空间不连续。
如何检测因内存碎片触发了
Full GC?
通过启动
java 时,添加 -XX:PrintFLSStatistics=1 参数来打印每次 gc 前后的 Heap 余量。较大的余量,可以怀
疑
Heap 中存在内存碎片过多。
HBase 中的内存碎片
HBase 为了提高写入性能,为每个 region 添加了一个内存写缓存-Memstore。当单个 Memstore 的大小达到
memstore.size 或 Heap 内存达到 hbase.regionserver.global.memstore.upperLimit/lowerLimit 百分比限制时,就会
触发整个
region 的 flush,最终将所有数据写入 HDFS 并释放 region 下所有 Memstores 占用的内存(GC 不一
定及时)。
Region flush 导致内存碎片的示意图: