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,并不只有在内存满或达到触发比例的时候,还有可能是因为内存碎片。

产生内存碎片的主要原因是:

  • 分配的大小不一。
  • 分配的空间不连续。
    如何检测因内存碎片触发了Full GC?
    通过启动java时,添加 -XX:PrintFLSStatistics=1 参数来打印每次gc前后的Heap余量。较大的余量,可以怀疑Heap中存在内存碎片过多。
    另外这篇blog有更详细的图文解释:

http://www.cloudera.com/blog/2011/02/avoiding-full-gcs-in-hbase-with-memstore-local-allocation-buffers-part-2/

HBase中的内存碎片

HBase为了提高写入性能,为每个region添加了一个内存写缓存-Memstore。当单个Memstore的大小达到memstore.size或Heap内存达到hbase.regionserver.global.memstore.upperLimit/lowerLimit百分比限制时,就会触发整个region的flush,最终将所有数据写入HDFS并释放region下所有Memstores占用的内存(GC不一定及时)。

Region flush导致内存碎片的示意图:

左边五颜六色的是不同的region在内存中的位置,它是无序的,因为客户端的请求是无规律的。此时假设黄色的region触发了flush,那么右边将会出现与之对应的多个空洞,即内存碎片。这张图以region为粒度,仅仅是为了更直观地表示这种现象。真实场景中,这些空洞是更细粒度的KeyValue级对象,它能直接导致创建对象时触发Full GC。

Arena Allocation

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

它的原理:

  • 创建一个大小固定的bytes数组和一个偏移量,默认值为0。
  • 分配对象时,将新对象的data bytes复制到数组中,数组的起始位置是偏移量,复制完成后为偏移量自增data.length的长度,这样做是防止下次复制数据时不会覆盖掉老数据(append)。
  • 当一个数组被充满时,创建一个新的数组。
  • 清理时,只需要释放掉这些数组,即可得到固定的大块连续内存。
    在Arena Allocation方案中,数组的大小影响空间连续性,越大内存连续性越好,但内存平均利用率会降低。

HBase的解决方案-MSLAB

MSLAB,全称是 MemStore-Local Allocation Buffer,是Cloudera在HBase 0.90.1时提交的一个patch里包含的特性。它基于Arena Allocation解决了HBase因Region flush导致的内存碎片问题。

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

  • MemstoreLAB为Memstore提供Allocator。
  • 创建一个2M(默认)的Chunk数组和一个chunk偏移量,默认值为0。
  • 当Memstore有新的KeyValue被插入时,通过KeyValue.getBuffer()取得data bytes数组。将data复制到Chunk数组起始位置为chunk偏移量处,并增加偏移量=偏移量+data.length。
  • 当一个chunk满了以后,再创建一个chunk。
  • 所有操作lock free,基于CMS原语。
    优势:

  • KeyValue原始数据在minor gc时被销毁。

  • 数据存放在2m大小的chunk中,chunk归属于memstore。
  • flush时,只需要释放多个2m的chunks,chunk未满也强制释放,从而为Heap腾出了多个2M大小的内存区间,减少碎片密集程度。
    开启MSLAB

hbase.hregion.memstore.mslab.enabled=true // 开启MSALB
hbase.hregion.memstore.mslab.chunksize=2m // chunk的大小,越大内存连续性越好,但内存平均利用率会降低
hbase.hregion.memstore.mslab.max.allocation=256K // 通过MSLAB分配的对象不能超过256K,否则直接在Heap上分配,256K够大了

本文来源于"阿里中间件团队播客",原文发表时间" 2011-06-22  "

利用Arena Allocation避免HBase触发Full GC相关推荐

  1. HBase之CMS GC调优

    HBase发展到现在,各种优化从未停止,GC优化更是重中之重,比如0.94版本提出的MemStoreLAB,MemStore Chunk Pool策略对写缓存MemStore进行优化开始,到0.96版 ...

  2. java触发full gc的几种情况概述

    前言 近期被问及这个问题,在此记录整理一下. System.gc()方法的调用 此方法的调用是建议JVM进行Full GC,虽然只是建议而非一定,但很多情况下它会触发 Full GC,从而增加Full ...

  3. 触发Full GC执行的情况 以及其它补充信息

    除直接调用System.gc外,触发Full GC执行的情况有如下四种.1. 旧生代空间不足旧生代空间只有在新生代对象转入及创建为大对象.大数组时才会出现不足的现象,当执行Full GC后空间仍然不足 ...

  4. 触发Full GC的原因

    当年轻代晋升到老年代的对象大小,并比目前老年代剩余的空间大小还要大时,会触发Full GC: 当老年代的空间使用率超过某阈值时,会触发Full GC: 当元空间不足时(JDK1.7永久代不足),也会触 ...

  5. 由「Metaspace容量不足触发CMS GC」从而引发的思考

    转载自  由「Metaspace容量不足触发CMS GC」从而引发的思考 某天早上,毛老师在群里问「cat 上怎么看 gc」. 好好的一个群 看到有 GC 的问题,立马做出小鸡搓手状. 之后毛老师发来 ...

  6. full gc JAVA_java触发full gc的几种情况概述

    前言 近期被问及这个问题,在此记录整理一下. System.gc()方法的调用 此方法的调用是建议JVM进行Full GC,虽然只是建议而非一定,但很多情况下它会触发 Full GC,从而增加Full ...

  7. 大数据学习笔记:利用JAVA项目操作HBase

    文章目录 一.Java类与HBase数据模型之间的对应关系 二.利用JAVA项目操作HBase (一)HBase表基本操作 1.创建Java项目HBaseDemo 2.在pom.xml添加对hadoo ...

  8. java 手动触发gc_java触发full gc的几种情况整理

    前言 近期被问及这个问题,在此记录整理一下. System.gc()方法的调用 此方法的调用是建议JVM进行Full GC,虽然只是建议而非一定,但很多情况下它会触发 Full GC,从而增加Full ...

  9. young GC和Full GC的区别、什么时候触发young gc和Full GC、如何优化GC

    young GC 和 Full GC 的含义及区别? young GC(新生代GC):指发生在新生代的垃圾收集动作,新生代中的对象朝生夕死,所以 Minor GC 非常频繁,回收速度也比较快. Ful ...

最新文章

  1. MLS 移动最小二乘
  2. 从系统的启动过程分析,为什么我们划分分区的时候 /sbin 、/bin、/lib、/dev不能做为独立的分区?...
  3. 数据结构与算法(3)——树(二叉、二叉搜索树)
  4. Cookie和Session实现保存登录状态免登录
  5. 电脑科学性计算机怎么用,怎么使用科学计算器59 000×(1+r)-2
  6. usaco-crypt1-pass
  7. 前端学习(2227):react之状态二
  8. block的界面间传值的使用
  9. 【Java】位运算符:左移右移
  10. MongoDB下载安装教程
  11. NandFlah 相关知识详解
  12. [单片机框架][bsp层][N32G4FR][bsp_flash] flash配置和使用
  13. 金融网络安全和反欺诈方法论,金融新兴技术成熟度几何?
  14. 删除docker container
  15. 企业物流管理系统使用教程
  16. 斜渐近线b为0为什么不存在_向量的奇技淫巧——斜坐标系
  17. php微信群发接口,微信公众平台群发接口问题
  18. Shell脚本中cp使用*号提示No such file
  19. SAR图像之斑点噪声
  20. kafka 消费者详解

热门文章

  1. mac scp工具_Mac远程ssh连接乌班图并实现爬虫操作
  2. java日期格式化代码的写法_Java中的`DateTimeFormatter`格式化代码中的`uuuu`与`yyyy`?...
  3. 永磁同步电机矢量控制中的双闭环是什么意思_三菱伺服控制器与变频器区别,三菱伺服控制器优势在哪?...
  4. java数据返回到界面,java后台获取网页ajax数据和返回数据简单源码
  5. java返回datatable_(转)在JAVA实现DataTable对象(三)——DataTable对象实现
  6. dgi数据治理_国外数据治理模型比较
  7. vs2008安装_Visual Studio2008安装教程
  8. 微擎php5.6无法上传图片,解决PHP5.6版本“No input file specified”的问题
  9. Vue中子组件如何向父组件传递数据?
  10. Spring Boot基础学习笔记08:Spring Boot整合Redis