内存,一个看不见也摸不着的东西,我们每天都在接触它但是却很少真正去了解过它。在我们学习程序语言时,是不是经常会接触内存泄漏、动态开辟、地址等等的词语?是的,它们均与我们所说的内存有着千丝万缕的关系,今天,我们便走进内存,简单了解其基本的构造。
内存的六大分区
我们常说的内存分区一般有两种分法,其一是常说的五大分区,分别是堆、栈、自由存储区、全局/静态存储区以及常量存储区;而另一种我们说是六大段,其分别是内核空间、栈、内存映射区、堆、数据段、代码段。
内核空间
通常,计算机会在默认情况在将高地址的一部分空间分配给内核。当然在不同的操作系统中分配的大小也是不一样的,通常Windows系统下会分配1GB或2GB的,Linux系统下一般会将高地址的1GB空间拿来给内核,在该空间是系统内核运行的空间,其中用户代码不能被读写,可以执行任意指令调动系统的一切资源,其主要作用在于进程管理、内存管理、文件管理、驱动管理以及网络管理等。
栈区(stack)
栈区,其与数据结构中的栈存储结构类似,满足先进后出的存取原则,栈区又可以称作为堆栈,其主要存贮的是非静态局部变量、函数参数以及返回值,在记录函数调用过程时,又称作栈帧或者过程活动记录,期地址总是向下增长。
内存映射段(mmap)
是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共
享内存,做进程间通信。在内存映射文件时,由一个文件到一块内存的映射,使用时通过内存映射文件时可以保留一个地址空间的区域,同时将物理存储器提交给该区域,使用内存映射文件处理存储于磁盘上的文件时,将不必在对文件执行I/O操作,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。
堆(heap)
这里的堆,其实与-数据结构中所建的大根堆与小根堆不同,它的行为反而与链表有些相似。堆上主要用于程序员申请动态的空间,使用结束后进行释放,否则会造成内存泄漏,堆的地址是向上增长的。
数据段(Data)
数据段用于存储全局变量和静态数据,即已初始化且初值不为0的全局变量和静态局部变量,属于静态的内存存储区,可读可写。同时数据段保存在目标文件中,其内容必须由程序初始化。
代码段(text)
主要保存可执行的代码以及只读常量,通常代码段是可共享的,故频繁执行的程序只需要在内存中拥有一份拷贝即可,同时其中保存的文件一般只有只读属性,放置用户或者其他程序对其进行修改。
内存模型图

例(练习)
分析以下代码中各变量以及各资源所在位置
int globalVar = 1; //globalVal属于全局变量,位于数据段
static int staticGlobalVar = 1;//staticGlobalVar属于静态全局变量,位于数据段
void Test()
{
static int staticVar = 1; //staticVar属于静态变量,位于数据段
int localVar = 1;//localVar非静态局部变量,位于栈
int num1[10] = {1, 2, 3, 4};
char char2[] = "abcd";
char* pChar3 = "abcd";
int* ptr1 = (int*)malloc(sizeof (int)*4);
int* ptr2 = (int*)calloc(4, sizeof(int));
int* ptr3 = (int*)realloc(ptr2, sizeof(int)*4);
free (ptr1);
free (ptr3);
}

欢迎大家批评指正,共同进步!


1万+

被折叠的 条评论
为什么被折叠?



