from:http://wangneng-168.iteye.com/blog/2100379

redis使用tcmalloc管理内存,当删除了redis的key后,通过redis的info命令查看内存使用情况,发现内存并没有释放,但是采用默认的jemalloc就不会有这个问题

以下是采用tcmalloc后删除key前和删除key后通过info看到的内存情况:

删除key前:

used_memory:13051400

used_memory_human:12.45M

used_memory_rss:16326656

used_memory_peak:13051400

used_memory_peak_human:12.45M

used_memory_lua:33792

mem_fragmentation_ratio:1.25

mem_allocator:tcmalloc-2.0

删除key

used_memory:835080

used_memory_human:815.51K

used_memory_rss:16392192

used_memory_peak:13051400

used_memory_peak_human:12.45M

used_memory_lua:33792

mem_fragmentation_ratio:19.63

mem_allocator:tcmalloc-2.0

以下是采用jemalloc后删除key前和删除key后通过info看到的内存情况:

删除key前:

used_memory:13047176

used_memory_human:12.44M

used_memory_rss:14704640

used_memory_peak:13047176

used_memory_peak_human:12.44M

used_memory_lua:33792

mem_fragmentation_ratio:1.13

mem_allocator:jemalloc-3.6.0

删除key

used_memory:830696

used_memory_human:811.23K

used_memory_rss:2318336

used_memory_peak:13047176

used_memory_peak_human:12.44M

used_memory_lua:33792

mem_fragmentation_ratio:2.79

mem_allocator:jemalloc-3.6.0

从结果看,删除大量的key后,采用jemalloc的redis分配的内存缩减为大约2M,而tcmalloc没有变化

TcMalloc的原理参看:

http://wenku.baidu.com/link?url=pzXI4OTNuoNGPKQ9MtKOX_60adNREkVe5m94QNuZMj0bsgCaxodpcVOLChWD4bjAgAQBSRNn2aCXzne9Mp4fShzm2a-Oxt02ohmbyrhcblW

其中提到:目前的tcmalloc版本不会把任何内存返还给操作系统,可见采用tcmalloc时redis实例占用的内存与redis使用内存的峰值有关

JeMalloc的原理可以参看:

http://club.alibabatech.org/article_detail.htm?articleId=36

其中提到:

回收流程大体和分配流程类似,有tcache机制的会将回收的块进行缓存,没有tcache机制的直接回收(不大于chunk的将对应的page状态进行修改,回收对应的run;大于chunk的直接munmap)。需要关注的是jemalloc何时会将内存还给操作系统,因为ptmalloc中存在因为使用top_chunk机制(详见华庭的文章)而使得内存无法还给操作系统的问题。目前看来,除了大内存直接munmap,jemalloc还有两种机制可以释放内存:

1.   当释放时发现某个chunk的所有内存都已经为脏(即分配后又回收)就把整个chunk释放;

2.   当arena中的page分配情况满足一个阈值时对dirty page进行purge(通过调用madvise来进行)。这个阈值的具体含义是该arena中的dirty page大小已经达到一个chunk的大小且占到了active page的1/opt_lg_dirty_mult(默认为1/32)。active page的意思是已经正在使用中的run的page,而dirty page就是其中已经分配后又回收的page。

上述两种机制保证了jemalloc不会出现类似ptmalloc中的内存无法交还给操作系统的问题

结论:慎用tcmalloc,采用jemalloc就好。

redis采用tcmalloc导致无法释放内存的问题的更多相关文章

  1. redis作为缓存场景使用,内存耗尽时,突然出现大量的逐出,在这个逐出的过程中阻塞正常的读写请求,导致 redis 短时间不可用

    redis 突然大量逐出导致读写请求block   内容目录: 现象 背景 原因 解决方案 ref 现象 redis作为缓存场景使用,内存耗尽时,突然出现大量的逐出,在这个逐出的过程中阻塞正常的读写请 ...

  2. /MT、/MD编译选项,以及可能引起在不同堆中申请、释放内存的问题

    一.MD(d).MT(d)编译选项的区别 1.编译选项的位置 以VS2005为例,这样子打开: 1)         打开项目的Property Pages对话框 2)         点击左侧C/C ...

  3. CF731C Socks并查集(森林),连边,贪心,森林遍历方式,动态开点释放内存

    http://codeforces.com/problemset/problem/731/C 这个题的题意是..小明的妈妈给小明留下了n只袜子,给你一个大小为n的颜色序列c 代表第i只袜子的颜色,小明 ...

  4. C/C++动态分配与释放内存的区别详细解析

    以下是对C与C++中动态分配与释放内存的区别进行了详细的分析介绍,需要的朋友可以过来参考下 1. malloc()函数1.1 malloc的全称是memory allocation,中文叫动态内存分配 ...

  5. Linux的虚拟内存管理-如何分配和释放内存,以提高服务器在高并发情况下的性能,从而降低了系统的负载

    Linux的虚拟内存管理有几个关键概念: Linux 虚拟地址空间如何分布?malloc和free是如何分配和释放内存?如何查看堆内内存的碎片情况?既然堆内内存brk和sbrk不能直接释放,为什么不全 ...

  6. 败家玩意儿!Redis 竟然浪费了这么多内存!

    作为内存数据库,内存空间大小对于 Redis 来说是至关重要的.内存越多,意味着存储的数据也会越多.但是不知道你有没有遇到过这样的情况,明明空间很大,但是内存的使用却不是很理想. 为什么会出现这样的情 ...

  7. Disque:Redis之父新开源的分布式内存作业队列

    Disque是Redis之父Salvatore Sanfilippo新开源的一个分布式内存消息代理.它适应于"Redis作为作业队列"的场景,但采用了一种专用.独立.可扩展且具有容 ...

  8. python里的del变量无法立刻释放内存的解决办法

    最近在python开发的时候,用到了一些很占用内存的操作,导致后续程序执行很慢甚至无法执行.探索了一下,最终解决了这个问题. 截图解释: python变量占用了内存,仅仅通过del变量的方式,只是让这 ...

  9. Linux释放内存

    在Linux系统下,我们一般不需要去释放内存,因为系统已经将内存管理的很好.但是凡事也有例外,有的时候内存会被缓存占用掉,导致系统使用SWAP空间影响性能,此时就需要执行释放内存(清理缓存)的操作了. ...

随机推荐

  1. 微信小程序(应用号)开发资源汇总整理 - 一直更新中

    开源项目 wechat-weapp-gank - 微信小程序版Gank客户端 wechat-dribbble - 微信小程序-Dribbble wechatApp-demo - 微信小程序 DEMO ...

  2. setRequestedOrientation设置屏幕方向

    void android.app.Activity.setRequestedOrientation(int requestedOrientation)   官方API解释:     Change th ...

  3. app让个别界面横屏,其他的为竖屏,解决如下

    app让个别界面横屏,其他的为竖屏,解决如下 APP设置里面,一定要设置可以旋转的方向 appdelegate里面重新系统方向代理 func application(application: UIAp ...

  4. 【代码笔记】iOS-判断字符串是否为空

    一,代码. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. ...

  5. MySQL分表自增ID解决方案

    当我们对MySQL进行分表操作后,将不能依赖MySQL的自动增量来产生唯一ID了,因为数据已经分散到多个表中. 应尽量避免使用自增IP来做为主键,为数据库分表操作带来极大的不便. 在postgreSQ ...

  6. 8、需求分析师要阅读的书籍 - IT软件人员书籍系列文章

    需求分析是软件项目开始阶段重要的一步.而需求分析是项目经理或产品经理需要经历的一环,所以说需求分析是项目经理或产品经理需要具备的知识.但是,项目角色中却分离出了需求分析师这个角色,也就是说,在大型的或 ...

  7. ORACLE与mysql中查询第n条到第m条的数据记录的方法

    ORACLE: SELECT * FROM             (                  SELECT 表名.*, ROWNUM AS CON FROM 表名 WHERE ROWNUM ...

  8. java多线程与单例模式(Singleton)不得不说的故事

    转发自:http://blog.csdn.net/ligang7560/article/details/50890282 单例模式的多种实现方式 我们都知道单例模式有几种常用的写法: - 饿汉模式 - ...

  9. python 打印对象的所有属性值

    def prn_obj(obj): print '\n'.join(['%s:%s' % item for item in obj.__dict__.items()])

  10. Hadoop自定义分组Group

    matadata: hadoop a spark a hive a hbase a tachyon a storm a redis a 自定义分组 import org.apache.hadoop.c ...