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):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...
随机推荐
- Linux命令之ip
ip [ OPTIONS ] OBJECT { COMMAND | help } 这一条命令几乎包含了所有使用方法,其中 对象OBJECT={ link | addr | addrlabel | ro ...
- mysql 获取当前日期及格式化(转)
MySQL 获取当前日期及日期格式 获取系统日期: NOW() 格式化日期: DATE_FORMAT(date, format) 注: date:时间字段,format:日期格式 select now ...
- 解决ubuntu系统中wireshark:Couldn't run /usr/bin/dumpcap in child process: Permission denied的问题
ubuntu系统运行WIreshark的时候,出现如下错误: Couldn't run /usr/bin/dumpcap in child process: Permission denied 解决办 ...
- Entity Framework part2
EF原理以XML方式打开edmx文件,这个XML的文件主要包含两大部分:Runtime是类模型部分,Designer是VS中的图形界面重点讨论的是Runtime部分,又分为三大部分:SSDL数据模型部 ...
- iOS开发-设置在使用NavigateController时View的顶部位置
最近我在开发中遇到了一个问题,在使用NavigationController时内部的ViewController的View总是与屏幕顶部对齐,而我们有时候不需要这种效果: 在开发过程中,我们可能会 ...
- Android Studio 生成aar包,并非debug包,而是release包
1.编写Module,作为library 下面是需要发布的aar包,上面的是随意的project 2.app依赖myLibrary 2.1 设置Project Structure 2.2 app依赖M ...
- struts-2-spring-2-jpa-ajax
http://struts.apache.org/docs/struts-2-spring-2-jpa-ajax.html
- ldr与adr的区别
参考: http://coon.blogbus.com/logs/2738861.html http://hi.baidu.com/for_guanghui/item/73e60bbcc8be15a2 ...
- Nice Messager隐私权政策
重视用户的隐私.您在使用我们的服务时,我们可能会收集和使用您的相关信息.我们希望通过本<隐私政策>向您说明,在使用我们的服务时,我们如何收集.使用.储存和分享这些信息,以及我们为您提供的访 ...
- 监控Coherence成员的加入和离开集群事件
对server事件的监控主要是实现MemberListener类,对Cache事件的监控主要通过MapListener 参考代码 package coherencetest; import com.t ...