趣谈Linux操作系统学习笔记-内存管理(20讲)

计算机进行计算

包括2方面:

1)  进程和线程对cpu的使用

2)  内存管理

 

独享内存空间的原理

每个进程都有自己独立的内存空间,如果直接使用物理空间,多个程序同时执行会有占用冲突。所以程序使用虚拟地址,系统负责把虚拟地址和物理地址映射起来

1、会议室和物理内存的关系

和会议室一样,内存都被分成一块块儿的,都编号了号,例如3F-10就是三楼十号会议室、内存页有这样一个地址。这个地址是实实在在的地址,通过这个地址我们就能够定位到物理内存地址

2、会产生什么问题呢?

3F-10打开三个相同的程序,都执行到某一步,比方说,打开三个计算机器,用户在这三个程序的界面、上分别输入10、100、1000,如果内存中的这个位置只能保存一个数,

那应该保存那个呢?这不就冲突了吗?

3、谁也不能直接访问物理地址

每个项目的物理地址对于进程不可见,谁也不能直接访问物理地址,操作系统会给进程分配一个虚拟地址。所有进程看到的这个地址都是一样的,里面的内存都是从0开始编号

4、在程序里面,指令写入的地址是虚拟地址

例如,位置我10M的内存区域,操作系统会提供一种机制,将不同的进程的虚拟地址和不同的物理地址映射起来

当程序要访问虚拟地址的时候,由内核的数据结构转换,转换成不同的物理地址,这样不同的进程运行的是时候,写入的是不同的物理地址这样就不会冲突了

 

规划虚拟地址空间

规划内存管理:

操作系统的内存管理包括3个方面:

一.  物理内存的管理, 相当于会议室管理员管理会议室

规划虚拟地址空间

二. 虚拟地址的管理,也即在项目组的视角,会议室的虚拟地址应该如何组织。

三. 物理地址和虚拟地址做好映射,也即会议室管理员如果管理映射表。

举个栗子:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int max_length = 128;
 5 
 6 char * generate(int length){
 7   int i;
 8   char * buffer = (char*) malloc (length+1);
 9   if (buffer == NULL)
10     return NULL;
11   for (i=0; i<length; i++){
12     buffer[i]=rand()%26+'a';
13   }
14   buffer[length]='\0';
15   return buffer;
16 }
17 
18 int main(int argc, char *argv[])
19 {
20   int num;
21   char * buffer;
22 
23   printf ("Input the string length : ");
24   scanf ("%d", &num);
25 
26   if(num > max_length){
27     num = max_length;
28   }
29 
30   buffer = generate(num);
31 
32   printf ("Random string is: %s\n",buffer);
33   free (buffer);
34 
35   return 0;
36 }

总结一下

这个简单的程序在使用内存时的几种方式:

1)代码需要放在内存里面;

2)全局变量,例如 max_length;

3)常量字符串"Input the string length : ";

4)函数栈,例如局部变量 num 是作为参数传给 generate 函数的,这里面涉及了函数调用,局部变量,函数参数等都是保存在函数栈上面的;

5)堆,malloc 分配的内存在堆里面;

6)这里面涉及对 glibc 的调用,所以 glibc 的代码是以 so 文件的形式存在的,也需要放在内存里面

内核部分还需要分配内存:

1)内核的代码要在内存里面;

2)内核中也有全局变量;

3)每个进程都要有一个 task_struct;

4)每个进程还有一个内核栈;

5)在内核里面也有动态分配的内存;

6)虚拟内存和物理内存的映射

 

内核的代码要在内存里面;内核中也有全局变量;每个进程都要有一个 task_struct;每个进程还有一个内核栈;在内核里面也有动态分配的内存;虚拟地址到物理地址的映射表放在哪里?

内存的排列

1)内存先分为用户态空间和内核态空间,用户态占用0到29号,内核态占用30到39号。

2) 用户态从0号到29号,依次是text segement(存放二进制可执行代码的位置段),data segment(存放初始化的静态常量),bss segment(存放未初始化的静态变量),heap(动态分配内存的区域),接下来是Memory Mapping segment,把文件映射进内存使用。接下来是栈地址段,

3) 内核态是共享的,无论哪个进程进入到内核,看到的空间和进程列表都是一样的,如果要访问公共资源需要加锁。

posted @ 2020-02-15 22:58  坚持,每天进步一点点  阅读(440)  评论(0编辑  收藏  举报