23. 在使用malloc分配内存的时候,该函数调用会对用户空间产生什么影响? 5
首先要先了解操作系统是如何管理内存的,然后再理解程序使用内存时是怎么管理就能回答这个问题了。
首先,第一个要解决的问题
1、操作系统是如何管理内存的?
当前电子计算机的CPU包括两大模块,运算器和控制器。
在微机原理相关知识中讲过,计算机对于存储器的写入和读取是根据相应寄存器存储的数据进行的,比如取指令就取出IP寄存器所指的存储位置存储的数据,这个存储位置由地址总线上当前的信号电平选定,存储器的每个单元被按序号组织成一个有序的列。电平变化指向不同的存储地址,(硬件部分只是做一铺垫,不再赘述,详见微机原理)
而多任务操作系统在执行后为了能同时执行多个应用程序,在处理器采用了分时轮转的技术,就是在多个程序的指令序列中来回切换执行。
而同时执行多个程序每个程序都需要独立寻址的内存空间,因为程序编写者不能预计程序在什么机器上被执行,在什么时候被执行,所以不能使用物理地址直接编程,而需要一个独立的从某个地址起始的(由操作系统决定)地址空间来编写程序。
那么操作系统为之提供的解决方案就是虚拟存储空间,操作系统会读取应用程序中的地址,然后由系统分配,计算,调度实际存储空间,比如32位的WINDOWS系统会为每个应用程序分配4G的虚拟空间,然后将实际使用的部分分页,重新写入物理内存中,并且按时序检查调度,决定继续分配或者收回内存。
第一个问题说清楚,我们就该考虑第二个问题,
应用程序是怎么使用虚拟内存空间的。
2、应用程序如何使用内存
现在绝大多数以机器码或者汇编作为目标程序的编译器都会采用C语言编译器的一些概念,比如内存管理。
应用程序在编译时会把内存分为三个区域管理,静态区域,栈区,堆区,
1、静态区
其中静态区域中存储了程序的全局变量,静态变量和符号表,常量之类的数据,这块区域在程序载入后最先分配,在程序结束时清出内存。
2、栈区
而栈区的管理方式类似于堆栈,里面存储局部变量,函数间传递的参数,这是由编译器自动生成代码管理的区域,不需要程序猿管理,但是需要注意编译器和操作系统指定的一些技术参数,比如栈区大小,如果某个程序的迭代层数很多,局部变量也很多科能就会出现栈溢出这种情况。
3、堆区
堆区是程序编写者需要手动管理的区域(某些语言),就像一个多用途的仓库,程序在运行中会分配或释放这些区域的数据,具体情况得看程序编写者。
而MALLOC函数就是手动分配一块内存区域,然后返回该区域指针,所以,MOLLOC是存放在堆区的。
在使用MALLOC后一定要记住释放,这些内存不会主动释放,只有在程序结束时,操作系统才会回收这块内存
如果你想知道这块内存在物理内存中的地址,需要得知当前程序占用了多少内存空间,分页情况,和这个内存的虚拟地址才能得到物理地址。(这一部分可以参考操作系统相关书籍,篇幅很大,不赘述。)