• 趣谈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]='';
    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
    ",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) 内核态是共享的,无论哪个进程进入到内核,看到的空间和进程列表都是一样的,如果要访问公共资源需要加锁。

  • 相关阅读:
    如何选择一款程序员理想中的显示器
    群英论道聚北京,共话PostgreSQL
    中国人民大学教授杜小勇:One Size Does not Fit All?
    4个技巧,教你如何用excel绘制出高大上的图表
    容易被误读的IOSTAT
    【Android Studio安装部署系列】四、Android SDK目录和作用分析
    【Android Studio安装部署系列】四、Android SDK目录和作用分析
    【Android Studio安装部署系列】四、Android SDK目录和作用分析
    【Android Studio安装部署系列】四、Android SDK目录和作用分析
    Java框架 面试题总结
  • 原文地址:https://www.cnblogs.com/mysky007/p/12315092.html
Copyright © 2020-2023  润新知