Linux内核笔记——内存管理之块内存分配
内核版本:linux-2.6.11
伙伴系统
伙伴系统是linux用于满足对不同大小块物理内存分配和释放请求的解决方案。
内存管理区
linux将物理内存分成三个内存管理区,分别为ZONE_DMA ZONE_NORMAL ZONE_HIGHMEM,并使用三个管理区描述符管理这三个ZONE。
管理区描述符里,有一个元素数为11的free_area数组,分别对应1、2、4、8、16.....不同块的大小,其中的每个元素的类型都是一个名为free_area的结构体,代码位置mm/mmzone.h
struct free_area {
struct list_head free_list;
unsigned long nr_free;
};
例如,该数组第三个元素的free_list保存了2的4次方即16个页框大小的空闲块链表,nr_free保存了空闲块的数量。
块内存分配函数
代码位置 mm/page_alloc.c
__rmqueue,传入参数为order和管理区zone的描述符指针。
static struct page *__rmqueue(struct zone *zone, usigned int order);
该函数会遍历2的order次方个页框大小的块空闲链表,若该链表空,则将order+1继续遍历,找到非空的空闲块链表后,取得它的第一个页框描述符。
page = list_entry(area->free_list.next, struct page, lru);
list_entry是一个宏,功能是取得一个成员变量的父结构体的指针,这里的意思是获得第一个参数area->free_list.next所在的page结构体的指针。
接着从链表中删除它的这一个页框描述符,并减少管理区描述符中的free_pages的值。
从上述过程可以知道,在获取order对应大小的空闲块时,如果没有正好大小的空闲块,那么将会从更大的空闲块中分离出order对应大小的空闲块,分离后剩下的部分要按照伙伴系统的规则正确的记录到管理区描述符的free_area数组中,expand函数在做这件事的同时,将我们需要的空闲块的第一个页框描述符的private字段设置成order(因为这个private仍然是空闲块未分割时的order值)。
return expand(zone, page, order, current_order, area);
至此,已经找到了需要的空闲块,返回其中的第一个页框描述符指针。
块内存释放函数
代码位置 mm/page_alloc.c
__free_pages_bulk,传入参数依次为要释放块的第一个页框描述符的指针,管理区的zone_mem_map字段(即管理区中的第一个页框描述符指针),管理区描述符,释放块的order值
static inline void __free_pages_bulk (struct page *page, struct page *base,
struct zone *zone, unsigned int order)
除去一些报错的代码后,主要过程就是寻找这个释放块的伙伴,并将二者合并。
函数实现部分,寻找伙伴这部分的代码理解起来比较晦涩,但十分聪明
buddy_idx = (page_idx ^ (1 << order));
buddy = base + buddy_idx;
page_idx是释放块在zone_mem_map中的下标,为了寻找它的伙伴块在zone_mem_map中的下标,将page_idx与块大小进行异或操作,该步骤可以将page_idx的第order位取反,即可以得到比page_idx高一个块大小的下标或者比page_idx低一个块大小的下标,这个下标值就是释放块的伙伴块在zone_mem_map中的下标。接着调用函数page_is_buddy来检查该伙伴块是否可以合并,若不行,退出循环,若行,将order+1并继续循环寻找是否有更大的伙伴块可以合并。
coalesced = base + page_idx;
set_page_order(coalesced, order);
list_add(&coalesced->lru, &zone->free_area[order].free_list);
zone->free_area[order].nr_free++;
循环结束后,page_idx记录了合并块的第一个页框描述符在zone_mem_map中的下标,加上base即zone_mem_map本身的地址后,得到合并块的第一个页框描述符的指针coalesced(这单词也够隐晦),该合并块成为最终的释放块,更新第一个页框描述符的private字段,并将其插入到适当链表,最后再增加该链表空闲块数量。
至此,块内存释放结束。
Linux内核笔记——内存管理之块内存分配的更多相关文章
- Linux内核笔记——进程管理之执行体
内核版本:linux-2.6.11 在Linux中,有多种执行体(指令流.执行单位),它们是CPU调度和分配资源的基本单位,它们是内核态可见的,即内核态下,每一种执行体都有对应的唯一数据结构task_ ...
- Linux内核笔记--内存管理之用户态进程内存分配
内核版本:linux-2.6.11 Linux在加载一个可执行程序的时候做了种种复杂的工作,内存分配是其中非常重要的一环,作为一个linux程序员必然会想要知道这个过程到底是怎么样的,内核源码会告诉你 ...
- Linux内核笔记——内存管理之slab分配器
内核版本:linux-2.6.11 内存区和内存对象 伙伴系统是linux用于满足对不同大小块内存分配和释放请求的解决方案,它为slab分配器提供页框分配请求的实现. 如果我们需要请求具有连续物理地址 ...
- 【转载】linux内核笔记之高端内存映射
原文:linux内核笔记之高端内存映射 在32位的系统上,内核使用第3GB~第4GB的线性地址空间,共1GB大小.内核将其中的前896MB与物理内存的0~896MB进行直接映射,即线性映射,将剩余的1 ...
- Linux中的Buffer Cache和Page Cache echo 3 > /proc/sys/vm/drop_caches Slab内存管理机制 SLUB内存管理机制
Linux中的Buffer Cache和Page Cache echo 3 > /proc/sys/vm/drop_caches Slab内存管理机制 SLUB内存管理机制 http://w ...
- 内存管理概述、内存分配与释放、地址映射机制(mm_struct, vm_area_struct)、malloc/free 的实现
http://blog.csdn.net/pi9nc/article/details/23334659 注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料 ...
- 【转载】linux内核笔记之进程地址空间
原文:linux内核笔记之进程地址空间 进程的地址空间由允许进程使用的全部线性地址组成,在32位系统中为0~3GB,每个进程看到的线性地址集合是不同的. 内核通过线性区的资源(数据结构)来表示线性地址 ...
- 垃圾回收GC:.Net自己主动内存管理 上(一)内存分配
垃圾回收GC:.Net自己主动内存管理 上(一)内存分配 垃圾回收GC:.Net自己主动内存管理 上(一)内存分配 垃圾回收GC:.Net自己主动内存管理 上(二)内存算法 垃圾回收GC:.Net自己 ...
- Win3内存管理之私有内存跟共享内存的申请与释放
Win3内存管理之私有内存跟共享内存的申请与释放 一丶内存简介私有内存申请 通过上一篇文章.我们理解了虚拟内存与物理内存的区别. 那么我们有API事专门申请虚拟内存与物理内存的. 有私有内存跟共享内存 ...
随机推荐
- 30多条mysql数据库优化方法,千万级数据库记录查询轻松解决(转载)
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- 微信的audio无法自动播放的问题
一.问题 最近做了一个html5的项目,里面涉及到音乐播放,项目要求音乐进入页面就自动播放,于是我就想到了html5的audio标签,将mp3引入进去. 1.在audio标签里引入了autoplay属 ...
- 6 VC维
1 VC维的定义 VC维其实就是第一个break point的之前的样本容量.标准定义是:对一个假设空间,如果存在N个样本能够被假设空间中的h按所有可能的2的N次方种形式分开,则称该假设空间能够把N个 ...
- 为WIN8 APP创建置顶desktop应用
Windows 8: TopMost window I am working on my next ambitious project “MouseTouch” which is multi to ...
- html图标插件
https://bitbucket.org/cleonello/jqplot/downloads/ 下载地址 http://www.cnblogs.com/yaozhenfa/p/jqplot-pie ...
- 软件设计Tips
模块-----角色----用户----部门 | | ------权限 | 系统管理-------业务管理-------报表展示 | | --------------------待 ...
- 逍遥安卓连接androidstudio
cmd 命令 D:\sdk\platform-tools>adb connect 127.0.0.1:21503
- PCA 协方差矩阵特征向量的计算
人脸识别中矩阵的维数n>>样本个数m. 计算矩阵A的主成分,根据PCA的原理,就是计算A的协方差矩阵A'A的特征值和特征向量,但是A'A有可能比较大,所以根据A'A的大小,可以计算AA'或 ...
- jquery追加内容
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- windows 用默认软件打开文档
System.Diagnostics.Process.Start("Explorer.exe", string.Format("/e, \"{0}\" ...