目录
一、程序地址空间
二、内存管理方式
1、分段式内存管理
2、分页式内存管理
3、段页式内存管理
三、关于内存管理内容补充(分页式)
1、页表简单呈现
2、访问权限位
3、缺页中断
4.内存置换算法
一、程序地址空间
创建父子进程同时访问同一变量,在子进程中对全局变量g_val进行修改
1 #include<stdio.h>
2 #include<unistd.h>
3
4 int g_val = 10;
5 int main()
6 {
7 int ret = fork();
8 if(ret<0){
9 printf("error fork\n");
10 }else if(ret==0){
11 g_val = 300;
12 printf("i am child, my g_val = %d,my &g_val = %p\n",g_val,&g_val);
13 }else{
14 printf("i am parent, my g_val = %d,my &g_val = %p\n",g_val, &g_val);
15 }
16 return 0;
17 }
现象: 输出结果俩者不相同,但俩变量的地址相同。
程序地址空间:进程的虚拟地址空间
系统为每一个程序运行通过mm_struct结构体(LInux下)所描述的一个虚拟的,连续的,完整的地址空间
我们进程中访问内存时候看到的地址其实都是虚拟地址,经过页表映射之后得到物理地址进行进而访问物理内存
进程并不直接访问物理地址,而是通过访问虚拟地址,进行映射访问物理地址的方式进行:
好处:
1、每个进程都有一个完整独立的虚拟地址空间,则地址可以随便使用,不同担心冲突
2、经过页表映射可以将数据存储在物理内存的任意位置,实现数据的离散式存储,提高内存利用率
3、在进行页表映射之后可以进行访问权限的控制
二、内存管理方式
1、分段式内存管理
将一个整体的地址空间划分为多个段(代码段、数据段、堆区、栈……)
作用: 更加利于编译器对于地址的管理
俩个要素:段表,地址组成
虚拟地址组成:段号,段内偏移量
段表:一种数据结构,其中描述的信息,段号,物理内存的一个起始地址
通过段号找到段表项,得到一块物理内存的起始地址
屋里内存起始地址+偏移量就是实际数据存储位置
2、分页式内存管理
将一个整体的地址空间划分为大量的小的分页page(当前一般默认都是4096字节为一页)
作用: 实现数据的离散存储,提高内存利用率
俩个关键要素:页表+虚拟地址组成
页表:页号、物理内存块起始地址、缺页中断位、访问权限位……
虚拟地址组成:页号+页内偏移
通过虚拟地址中的页号,在页表中找到对应的页表项,得到一个物理内存块的起始地址,加上页内偏移量就是实际的访问位置
二者不同的区别在于应用方向不同,分段式利于地址管理,分页式更加倾向于碎片化管理,提高内存利用率以及内存访问控制
3、段页式内存管理
先将地址空间进行分段,然后在每个分段内使用分页进行管理(集合了分段式与分页式的优势)
三、关于内存管理内容补充(分页式)
1、页表简单呈现
2、访问权限位
标记当前的地址能够进行什么操作
简单举例:
0号地址,也就是NULL,这个地址既不可读也不可写,因此一旦解引用或者修改则会内存访问错误
const修饰的常变量,具有常性,其实就是访问权限上只读
代码段的所有地址,都是只读的
3、缺页中断
当进程要访问一块内存时,经过页表映射的时候发现缺页中断位被置位(这个地址原先的数据现在不在内存中),则触发缺页中断
内存交换:
一个程序运行就要占据大量内存,但是物理内存是有限的,意味着内容总有耗尽时候
大佬们就有想法:按照某种规则将内存中的某些数据从内存中移出去,放到硬盘中存起来(放入swap分区)交换分区一般32G以内都是内存的俩倍
当我们访问数据的时候,刚好就是被移出去的数据时,就会触发缺页中断
触发缺页中断后,就需要重新进行内存置换,将数据从交换分区置换到内存中进行访问
4.内存置换算法
内存不够的时候,把哪些数据移出去放到交换分区上存储
LRU--最久未使用 LFU--最少未使用
操作系统中可以使用LRU(least recently used)内存淘汰旧数据的策略,如果内存需要加载新数据但空间又不足,则会按照最近访问时间进行排序,并将最老的数据淘汰,假设现在内存空间大小为6,原本内存中没有数据,对内存中数据的访问顺序如下: 1,2,5,3,4,6,1,4,3,6,7,8,3,9 则缺页次数为()
LRU栈:当前引用不在栈中,且栈未满,放到栈顶;栈满,删除栈底,放到栈顶。当前引用在栈中,删除栈中原先位置,放到栈顶。
缺页:当前引用不在页的某个帧中,即缺页。而LRU只是确定被置换的那个引用,即LRU栈底引用。
前6次均缺页,因为每次的引用都不在已有的页中,缺页次数6,当前LRU栈:6->4->3->5->2->1
第7次为1,在页中,不缺页,当前LRU栈:1->6->4->3->5->2
第8次为4,在页中,不缺页,当前LRU栈:4->1->6->3->5->2
第9次为3,在页中,不缺页,当前LRU栈:3->4->1->6->5->2
第10次为6,在页中,不缺页,当前LRU栈:6->3->4->1->5->2
第11次为7,不在页中,缺页。删除栈底2,将7放到栈顶。当前LRU栈:7->6->3->4->1->5
第12次为8,不在页中,缺页。删除栈底5,将8放到栈顶。当前LRU栈:8->7->6->3->4->1
第13次为3,在页中,不缺页。当前LRU栈:3->8->7->6->4->1
第14次为9,不在页中,缺页。删除栈底1,将9放到栈顶。当前LRU栈:9->3->8->7->6->4
综上,缺页9次。