Linux内核设计基础(五)之内存管理
我感觉学习操作系统首先要从内存分配和管理入手。
首先我们应该知道现代操作系统是以页为单位进行内存管理的,32位体系结构支持4KB的页。而64位体系结构支持8KB的页。页是用来分配的。怎样才干进行高效和充分的利用。这是内存管理单元(MMU)应当细致考虑的。
页分配
内核用结构体struct page表示每一个物理页。内核用这一结构来管理系统中全部的页,由于内核须要知道一个页是否空暇(也就是页有没有被分配)。假设页已经被分配,内核须要知道谁拥有这个页,拥有者可能是用户空间进程、动态分配的内核数据、静态内核代码或页快速缓存。我们用页表来统一管理全部的struct page。另外内核用区对具有相似特性的页进行分组。
主要是存在以下两种制约:
- 一些硬件仅仅能用某些特定的内存地址运行DMA(直接内存訪问)
- 一些体系结构的内存的物理寻址范围比虚拟寻址范围大得多。
这样,就有一些内存不能永久地映射到内核空间(高端内存)
- ZONE_DMA——这个区包括的页能用来运行DMA操作。
- ZONE_DMA32——同上,只是仅仅能被32位设备訪问。
- ZONE_NORMAL——这个区包括的都是能正常映射的页。
- ZONE_HIGHEM——高端内存,当中的页并不能永久映射到内核地址空间。
slab层
用于频繁使用的数据结构的缓存。且避免因频繁分配和使用导致的内存碎片。slab层是由快速缓存组成的,而每一个快速缓存能够由多个slab组成,slab由一个或多个物理上连续的页组成。每一个slab都包括一些缓存的数据结构。这样说还是非常抽象,举个inode的样例。
inode是磁盘文件在内存中的体现,会频繁地进行创建和释放,所以有必要进行缓存管理。在这里快速缓存是inode_cachep。它由多个slab组成,而每一个slab包括尽可能多的struct inode对象。
所以当我们须要一个新的inode结构时,不必现创建,仅仅需从部分满或空的slab返回一个指向已分配但未使用的inode结构的指针就可以。当内核使用完这个inode对象时。slab分配器就把该对象标记为空暇,留给后来者。
再举个进程控制块的样例。
我们知道进程在不停地创建和消除,而用struct task_struct去管理一个进程。不停的创建和释放task_struct会非常费时。所以内核初始化期间,在fork_init()中着手创建快速缓存:
struct kmem_cache *task_struct_cachep;(内核用这个全局变量存放指向task_struct快速缓存的指针)
task_struct_cachep = kmem_cache_create("task_struct",
sizeof(struct task_struct),
ARCH_MIN_TASKALIGN,
SLAB_PANIC | SLAB_NOTRACK,
NULL);
这样当我们创建进程(运行fork)时,仅仅需从这个快速缓存中索取就可以:
struct task_struct *tsk;
tsk = kmem_cache_alloc(task_struct_cachep, GFP_KERNEL);
if(!tsk) return NULL;
内核栈
我们在进程时要注意节省栈资源。要控制函数内的局部变量。尽量不要出现大型数组或大型结构体。尤其对于内核栈,一旦造成溢出,就会影响到内核数据(如thread_info)。所以应当优先考虑动态分配。另外一个进程的内核栈和中断栈是分开的,这样能够减轻内核栈的负担(一个内核栈仅仅占1页或2页)。
Linux内核设计基础(五)之内存管理的更多相关文章
- Linux内核入门到放弃-内存管理-《深入Linux内核架构》笔记
概述 内存管理的实现涵盖了许多领域: 内存中的物理内存页管理 分配大块内存的伙伴系统 分配较小内存块的slab.slub和slob分配器 分配非连续内存块的vmalloc机制 进程的地址空间 在IA- ...
- Linux内核设计笔记12——内存管理
内存管理学习笔记 页 页是内核管理内存的基本单位,内存管理单元(MMU,管理内存并把虚拟地址转化为物理地址的硬件)通常以页为单位进行处理,从虚拟内存的角度看,页就是最小单位. struct page{ ...
- linux内核(四)内存管理单元MMU
1,基本概念 一个程序运行时没必要全部都同时装入内存,只需要把当前需要运行的部分装入内存即可,这样就使得一个大程序可以在较小的内存中运行,也使得内存中可以同时装入更多的程序并发执行,从用户角度看,该系 ...
- 分析linux内核中的slub内存管理算法
1. 分析的linux内核源码版本为4.18.0 2. 与slub相关的内核配置项为CONFIG_SLUB 3. 一切都从一个结构体数组kmalloc_caches开始,它的原型如下: ] __ro_ ...
- Linux内核学习笔记-2.进程管理
原创文章,转载请注明:Linux内核学习笔记-2.进程管理) By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...
- 解析Linux内核的基本的模块管理与时间管理操作---超时处理【转】
转自:http://www.jb51.net/article/79960.htm 这篇文章主要介绍了Linux内核的基本的模块管理与时间管理操作,包括模块加载卸载函数的使用和定时器的用法等知识,需要的 ...
- linux kernel学习笔记-5内存管理_转
void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...
- Linux内核设计基础(十)之内核开发与总结
(1)Linux层次结构: (2)Linux内核组成: 主要由进程调度(SCHED).内存管理(MM).虚拟文件系统(VFS).网络接口(NET)和进程间通信(IPC)等5个子系统组成. (3)与Un ...
- Linux环境进程间通信(五): 共享内存(上)
linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...
随机推荐
- CF 612C. Replace To Make Regular Bracket Sequence【括号匹配】
[链接]:CF [题意]:给你一个只含有括号的字符串,你可以将一种类型的左括号改成另外一种类型,右括号改成另外一种右括号 问你最少修改多少次,才能使得这个字符串匹配,输出次数 [分析]: 本题用到了栈 ...
- POJ2032 Building a Space Station(Kruskal)(并查集)
Building a Space Station Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 7469 Accepte ...
- sqlplus version
$ export ORACLE_HOME=/opt/oraClient/11.2.0.4$ $ ./sqlplus -version SQL*Plus: Release 11.2.0.4.0 Prod ...
- Android中的MVC,MVP和MVVM
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha MVC,MVP,MVVM的区别 #MVC 软件可以分为三部分 视图(View):用户界面 ...
- POJ 3537:Crosses and Crosses(Multi-Nim)
[题目链接] http://poj.org/problem?id=3537 [题目大意] 在一个1*n的方格纸上下棋,谁先连三子谁就赢了,问必胜的是谁. [题解] 我们发现对于一个n规模的游戏.在i位 ...
- 【分块】bzoj3295 [Cqoi2011]动态逆序对
考虑每次删除pos位置一个数x后,所造成的的影响就是,逆序对的个数少了在1~pos-1中大于x的数的个数加上pos+1~n中小于x的数的个数. 那么我们需要的操作就只有查询区间内比某数大(小)的个数. ...
- 1.5(java学习笔记)this关键字
this关键字主要有三个作用 1.调用本类中的属性. public class TextThis { public static void main(String[] args){ Person p1 ...
- redis踩坑记
本来打算给一批主库做从库,用来读取数据,还不想碰主库数据. 主库redis2.8.12,从库一开始没注意,docker了一个3.1的,结果slaveof之后命令不兼容,下了一个2.8的(2.8.23好 ...
- Java高级架构师(一)第20节:X-gen生成需要的Action
package cn.javass.themes.smvcsm.actions; import cn.javass.xgen.genconf.vo.ModuleConfModel; import cn ...
- C++类的复习
1.C++ 类的声明:class class_name{ private: /* *私有的数据和成员函数 *只能被本类中的成员函数引用,类外不能调用 ...