Linux内存管理机制:
1、 为解决以下几个问题:
如何使进程的地址空间隔离;如何提高内存的使用效率;如何解决程序运行时的重定位问题。
2、 虚拟地址空间:0~3G为用户地址空间,3G-4G为内核内存空间,其中每个进程有单独的用户地址空间,内核内存空间为共享的。
进程的用户地址空间包含:代码段、数据段,BSS段(未初始化的全局变量),堆区、栈区等。用户空间的虚拟地址和物理地址则采用了多级页表进行映射。
物理地址空间:其中内核内存的3G+(0~896M)地址直接映射物理内存空间中(物理内存映射区域),其他地方被称为高端内存区(ZONE_HIGHEM)。
3、 Kmalloc:分配内核的内存,保证物理和虚拟地址均连续,释放用Kfree
4、 Vmalloc: 分配内核的内存,只保证虚拟地址连续。物理地址不一定连续。释放用vfree
5、 线程和进程的区别:进程是资源分配和管理的单位,线程是调度的基本单位,进程有独立的地址空间,拥有PCB,其中包含进程标识符(非负整数)、进程资源、进程调度信息、进程间通信相关资源、处理机状态(便于调度后恢复原状态)等,线程具有单独的堆栈和寄存器,保存自己允许的相关上下文,具有TCB。同一进程中的线程共享进程的一些资源,例如文件、信号量等。
Linux进程调度机制:
1、 进程分为:I/O消耗型和处理器消耗型,调度程序需要平衡两个目标:进程响应速度和系统利用率(吞吐量)。
2、 调度器以模块方式提供,允许不同类型的进程可以有针对性地选择调度算法。考虑进程优先级(nice值)和运行时间片。对于普通进程,采用动态优先级调度,对于实时进程,采用FIFO或时间片轮转(RR)调度策略。进程PCB中存在一个参数用来描述其调度策略和相关的优先级的值。实时进程始终比普通进程的优先级要高,能够抢占处理器。
3、 CFS的公平策略:假设现在系统有A,B,C三个进程,A.weight=1,B.weight=2,C.weight=3.那么我们可以计算出整个公平调度队列的总权重是cfs_rq.weight = 6,很自然的想法就是,公平就是你在重量中占的比重的多少来拍你的重要性,那么,A的重要性就是1/6,同理,B和C的重要性分别是2/6,3/6.很显然C最重要就应改被先调度,而且占用的资源也应该最多,即假设A,B,C运行一遍的总时间假设是6个时间单位的话,A占1个单位,B占2个单位,C占三个单位。
4、 时间记账(更新虚拟实时vruntime的值),选择进程(可运行队列采用rbtree来组织,选择最左边的叶子节点),使正运行的进程睡眠,并从可运行队列移出到等待队列中,等待指定的事件或相关信号唤醒。
5、 何种情况下会发生调度:
A:有进程执行完毕
B:等待I/O,阻塞后进入睡眠状态
C:执行完系统调用程序后返回用户进程