核心数据结构

linux 2.6 的内存管理支持NUMA(Non Uniform Memory Access Achitecture),即非一致内存访问体系,在该体系中存在多个CPU,并且拥有分离的存储器以及共享存储器。因此在linux的代码中将每一个CPU的可访问内存定义为一个内存节点。总体上linux采取了节点、域、页面三级结构描述物理内存,核心数据结构如下:

typedef struct pglist_data { //内存节点数据结构
struct zone node_zones[MAX_NR_ZONES];
//略}
struct zone {//域数据结构
//略
//#define MAX_ORDER 11
struct free_area free_area[MAX_ORDER]; //页管理 MAX_ORDER为11
//略}

buddy算法概述:

free_area对应一个域中的物理页面,页面的管理采用buddy算法。在buddy算法中物理内存被分为11个组,其中第0,1,N个组分别对应20、2N个连续物理界面。当分配2N 个页面是就会到相应的组去寻找,若没有则向下寻找同时向上归并空闲块。举例如下:

第一次:初始情况,所有的页面状态为可用;

第二次:申请一个页面,因此数组0的页面被获取;

第三次:申请两个页面,因此数组1的页面给获取;

第四次:仍然申请两个页面,此时数据1已经无空闲块,遍历至数组2;获取两个页面,同时将数组2的剩余两个页面向上归并,最终数组2满,而数组1空闲;

buddy算法实现(根据linux 2.6.11版本)

核心函数为mm/page_alloc.c中的__alloc_pages,函数原型为:

struct page * fastcall
__alloc_pages(unsigned int gfp_mask, //申请修饰符,如__GPF_WAIT表示分配器可以休眠
unsigned int order, //申请页面的阶数
struct zonelist *zonelist)

在该函数中调用:page = buffered_rmqueue(z, order, gfp_mask);

buffered_rmqueue调用__rmqueue和expand分别完成buddy算法中的申请页面查找,和分拆后的向上空闲块归并,代码如下:

static struct page *__rmqueue(struct zone *zone, unsigned int order)
{
struct free_area * area;
unsigned int current_order;
struct page *page; for (current_order = order; current_order < MAX_ORDER; ++current_order) {
area = zone->free_area + current_order;//到与current_order阶数对应的free_area数组元素
if (list_empty(&area->free_list))//当前area下无空闲块
continue;
page = list_entry(area->free_list.next, struct page, lru); //在area的free_list中获取属于LRU(当前最久未使用页面)
list_del(&page->lru);//在最久未使用页面列表中删除该页面
rmv_page_order(page);
area->nr_free--;//该area的可用页面-1
zone->free_pages -= 1UL << order; //整个域的页面减去2的阶层次个页面
return expand(zone, page, order, current_order, area);//拆分归并,current_order为实际获取页面的阶层数,如上例中的数组2
}
return NULL;
}
static inline struct page *
expand(struct zone *zone, struct page *page,
int low, int high, struct free_area *area)
{
unsigned long size = << high;//获取页面的数组所包含页面数量,如数组2包含4个页面 while (high > low) {//若实际阶层数大于申请阶层数,则需要进行拆分归并
area--;//向上查找
high--;
size >>= ;//size>>1表示上一级的全部页面数(举例,若在第4组即16个页面处,申请4个页面,那么剩下的12个会分为8个(size>>=1)和4个(size>>=2)填充到上面的数组里)
BUG_ON(bad_range(zone, &page[size]));
list_add(&page[size].lru, &area->free_list);//将上一级free_list变为空闲块
area->nr_free++;//该级可用页面数增加
set_page_order(&page[size], high);
}
return page;
}

Linux 2.6 源码学习-内存管理-buddy算法的更多相关文章

  1. MongoDB源码概述——内存管理和存储引擎

    原文地址:http://creator.cnblogs.com/ 数据存储: 之前在介绍Journal的时候有说到为什么MongoDB会先把数据放入内存,而不是直接持久化到数据库存储文件,这与Mong ...

  2. Memcached源码分析——内存管理

    注:这篇内容极其混乱 推荐学习这篇博客.博客的地址:http://kenby.iteye.com/blog/1423989 基本元素item item是Memcached中记录存储的基本单元,用户向m ...

  3. Paddle源码之内存管理技术

    前言 在深度学习模型训练中,每次迭代过程中都涉及到Tensor的创建和销毁,伴随着的是内存的频繁 malloc和free操作,可能对模型训练带来不必要的 overhead. 在主流的深度学习框架中,会 ...

  4. nginx源码学习----内存池

    最近在进行监控平台的设计,之前一直觉得C/C++中最棘手的部分是内存的管理上,远不止new/delete.malloc/free这么简单.随着代码量的递增,程序结构复杂度的提高.各种内存方面的问题悄然 ...

  5. redis源码笔记-内存管理zmalloc.c

    redis的内存分配主要就是对malloc和free进行了一层简单的封装.具体的实现在zmalloc.h和zmalloc.c中.本文将对redis的内存管理相关几个比较重要的函数做逐一的介绍 参考: ...

  6. Vben Admin 源码学习:状态管理-错误日志

    0x00 前言 本文将对 Vue-Vben-Admin 的状态管理实现源码进行分析解读,耐心读完,相信您一定会有所收获! 0x01 errorLog.ts 错误日志 文件 src\store\modu ...

  7. Vben Admin 源码学习:状态管理-角色权限

    前言 本文将对 Vue-Vben-Admin 角色权限的状态管理进行源码解读,耐心读完,相信您一定会有所收获! 更多系列文章详见专栏   Vben Admin 项目分析&实践 . 本文涉及到角 ...

  8. linux 0.11 源码学习+ IO模型

    http://www.cnblogs.com/Fredric-2013/category/696688.html

  9. STL源码学习----lower_bound和upper_bound算法

    转自:http://www.cnblogs.com/cobbliu/archive/2012/05/21/2512249.html 先贴一下自己的二分代码: #include <cstdio&g ...

随机推荐

  1. lphp输出控制output controll(header, ob_xxx)

    关于php的output controll参考文档: http://gywbd.github.io/posts/2015/1/php-output-buffer-in-deep.html http:/ ...

  2. Java多线程开发技巧

    很多开发者谈到Java多线程开发,仅仅停留在new Thread(...).start()或直接使用Executor框架这个层面,对于线程的管理和控制却不够深入,通过读<Java并发编程实践&g ...

  3. Linux_arm驱动之按键模拟脉冲实现定时器的精确计时

    /***************************************************************** 内核驱动部分button_ker.c ************** ...

  4. sqlite3 根据实体自动生成建表语句

      public class BuildSqlTool { public static string GetCreateTableSql(object t) { //CREATE TABLE &quo ...

  5. php-4种排序

    <?php$arr = array(1, 43, 54, 62, 21, 66, 32, 78, 36, 76, 39); //1. 冒泡排序 //在要排序的一组数中,对当前还未排好的序列,从前 ...

  6. hdoj 2022 海选女主角

    Problem Description potato老师虽然很喜欢教书,但是迫于生活压力,不得不想办法在业余时间挣点外快以养家糊口.“做什么比较挣钱呢?筛沙子没力气,看大门又不够帅...”potato ...

  7. vc11(vs2012)下编译php

    需要原料: vs2012.php源码 1.本机的mingw没搞定,参考网上文章尝试vs2012编译,借助vs2012自带的命令行工具: 需要去bison官网下载bison.exe放在“c:/windo ...

  8. java excle导出合计字段值

    效果图: 代码实现: 解释: // 四个参数分别是:起始行,起始列,结束行,结束列 sheet.addMergedRegion(new Region(0, (short) (celln + 1), 0 ...

  9. Java并发

    Java并发编程:Thread类的使用 http://www.cnblogs.com/dolphin0520/p/3920357.html 一.线程的状态 在正式学习Thread类中的具体方法之前,我 ...

  10. 设计模式可复用面向对象软件设计基础之对象创建型模式—ABSTRACT FACTORY( 抽象工厂)

    意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 适用性 在以下情况可以使用 Abstract Factory模式 • 一个系统要独立于它的产品的创建.组合和表示时. • 一 ...