memcached内存管理算法

简单的写写,看完了memcached的这部分代码之后觉得跟我的ccache还是很像的.

1) 分配

memcached中的内存全部由类型为slabclass_t的结构体保存

typedef struct {
unsigned int size;      /* sizes of items */
unsigned int perslab;   /* how many items per slab */

void **slots;           /* list of item ptrs */
unsigned int sl_total;  /* size of previous array */
unsigned int sl_curr;   /* first free slot */

void *end_page_ptr;         /* pointer to next free item at end of page, or 0 */
unsigned int end_page_free; /* number of items remaining at end of last alloced page */

unsigned int slabs;     /* how many slabs were allocated for this class */

void **slab_list;       /* array of slab pointers */
unsigned int list_size; /* size of prev array */

unsigned int killing;  /* index+1 of dying slab, or zero if none */
} slabclass_t;

有一个全局的slabclass_t的数组,slabclass_t中的size字段保存每个slab所能保存的数据大小.在这个slabclass_t数组中,size字段都是递增的,递增的因子由slabs_init函数中的第二个参数factor参数指定.比如说,假如factor是2,那么如果第一个slabclass_t的size是unsigned int size = sizeof(item) + settings.chunk_size;(也是在slabs_init函数中的语句),那么下一个slabclass_t的size就是size*factor(这里忽略对齐的因素).

于是乎,假设第一个slab能保存8byte的数据,factor为2,那么接下来的slab的size依次为16byte,32byte...

每次需要分配内存,都需要根据所需分配的尺寸查找大于该尺寸的最小尺寸的slab,比如还是前面的那个slab模型,如果现在需要分配30byte的空间,查找得到大于30byte的最小slab尺寸是32byte,于是就从这个slab中查找item分配给它.

但是这里有一个问题,就是多余资源的浪费,前面说的30byte只是浪费了2byte,但是如果现在要分配的是17byte,那么就浪费了15byte,浪费了将近50%!因此才有了前面需要指定factor的原因,使用者可以根据需要指定不同的增长factor,以降低资源的浪费.

2) 淘汰

淘汰采用的是LRU算法,所有的最近使用的item保存在static item *tails[LARGEST_ID];(item.c)中,已经分配的内存会以链表的形式保存在这个数组中,如果对应的slab已经分配不到足够的内存,就到这个链表中查询,淘汰的依据是item结构体中的exptime字段.

简单分析到此,需要更详细的解释就去看代码吧,memcached中与这部分的代码在slab.h(.c)/item.h(.c)中,两个关键的结构体是item和slabclass_t.

时间: 2024-12-29 03:22:12

memcached内存管理算法的相关文章

C++内存管理变革

引言 C/C++语言的内存管理经历了几次变革,但至今仍未能趋于成熟.这几次变革主要包括: 1. 从malloc/free到new/delete.这场变革是OOP技术兴起的产物.C++是强类型语言,new/delete的主要成果也就是加强了类型观念,减少了强制类型转换的需求.但是从内存管理角度看,这个变革并没有多少的突破性. 2. 从new/delete到内存配置器(allocator).自从STL被纳入C++标准库后,C++世界产生了巨大的变化.而从内存管理角度来看,allocator的引入也是

JVM内存管理:GC算法精解---分代搜集算法

引言 何为终极算法? 其实就是现在的JVM采用的算法,并非真正的终极.说不定若干年以后,还会有新的终极算法,而且几乎是一定会有,因为LZ相信高人们的能力. 那么分代搜集算法是怎么处理GC的呢? 对象分类 上一章已经说过,分代搜集算法是针对对象的不同特性,而使用适合的算法,这里面并没有实际上的新算法产生.与其说分代搜集算法是第四个算法,不如说它是对前三个算法的实际应用. 首先我们来探讨一下对象的不同特性,接下来LZ和各位来一起给这些对象选择GC算法. 内存中的对象按照生命周期的长短大致可以分为三种

Java内存管理及GC算法

概述 内存划分 虚拟机规范中将内存分为六大部分,分别为PC寄存器.JAVA虚拟机栈.JAVA堆.方法区.运行时常量及本地方法栈. 1.PC寄存器:线程独占: 2.JAVA虚拟机栈:线程独有:JAVA虚拟机栈是在创建线程的同时创建的,用于存储栈帧,JAVA虚拟机栈也是线程独有的. 3.JAVA堆:全局共享: 4.方法区:全局共享:它主要存储的是 运行时常量池 字段信息 方法信息 构造方法 普通函数的字节码内容以及一些特殊方法. 5.本地方法栈:线程独有,本地方法栈是一个传统的栈,它用来支持nati

我所理解的内存分配算法#1

内存分配从本质上来说是一种空间管理算法,给你一块连续的空间,提供存储服务,那么你的空间管理跟分配要采用什么样的算法才会比较高效? Bump-the-Pointer Bump-the-Pointer是最简单的算法.HotSpot的MM白皮书是这么描述btp的, That is, the end of the previously allocated object is always kept track of. When a new allocation request needs to be s

《高性能Linux服务器构建实战》——3.3节Memcached的管理与性能监控

3.3 Memcached的管理与性能监控 3.3.1 如何管理Memcached 1.通过Memcached的监听端口进行管理 Memcached的管理相对比较容易,通过命令行登录到Memcached的监听端口,然后执行一些命令,通过这些命令的输入即可查看Memcached的运行状态. 管理Memcached的命令如下: stats,统计Memcached的各种信息. stats reset,重新统计数据. stats slabs,显示slabs信息.通过这个命令能获取每个slabs的chun

聊聊内存管理

这篇文章我们聊聊内存管理. 本来我想不针对于任何具体的操作系统来谈内存管理,但是又觉得不接地气.言之无物.所以我决定在阐述概念的同时,还针对IA32平台Linux下的内存管理做简要的介绍,并且以实验来证明结论.以下内容分拆为几个大标题和小节,内容前后承接. 物理地址空间 首先,什么是物理地址空间?我们知道CPU与外部进行信息传递的公用通道就是总线,一般而言,CPU有三大总线:控制总线.数据总线.地址总线.这三类总线在一定程度上决定了CPU对外部设备的控制和数据传送能力.其中地址总线决定了CPU能

c#内存管理.

尽管在.net framework中我们不太需要关注内存管理和垃圾回收这方面的问题,但是出于提高我们应用程序性能的目的,在我们的脑子里还是需要有这方面的意识.明白内存管理的基本行为将有助于我们解释我们程序中变量是如何操作的.在本文中我将讨论栈和堆的一些基本知识,变量的类型和某些变量的工作原理. 当你在执行程序的时候内存中有两个地方用于存储程序变量.如果你还不知道,那么就来看看堆和栈的概念.堆和栈都是用于帮助我们程序运行的,包含某些特殊信息的操作系统内存模块.那么堆和栈有什么不同呢? 堆VS栈的区

PHP原理之内存管理中难懂的几个点

PHP的内存管理, 分为俩大部分, 第一部分是PHP自身的内存管理, 这部分主要的内容就是引用计数, 写时复制, 等等面向应用的层面的管理. 而第二部分就是今天我要介绍的, zend_alloc中描写的关于PHP自身的内存管理, 包括它是如何管理可用内存, 如何分配内存等. 另外, 为什么要写这个呢, 因为之前并没有任何资料来介绍PHP内存管理中使用的策略, 数据结构, 或者算法. 而在我们平时开发扩展, 修复PHP的bug的时候, 却对这一部分的知识需要有一个良好的理解. PHP开发组内的很多

Android内存管理简述

相信一步步走过来的Android从业者,每个人都会遇到OOM的情况.如何避免和防范OOM的出现,对于每一个程序员来说确实是一门必不可少的能力.今天我们就谈谈在Android平台下内存的管理之道,开始今天的主题之前,先再次回顾两个概念. 内存泄漏:对象在内存heap堆中中分配的空间,当不再使用或没有引用指向的情况下,仍不能被GC正常回收的情况.多数出现在不合理的编码情况下,比如在Activity中注册了一个广播接收器,但是在页面关闭的时候进行unRegister,就会出现内存溢出的现象.通常情况下