linux 内存管理

来源:互联网 发布:网络金融生态圈 编辑:程序博客网 时间:2024/06/08 00:27

linux系统为了更好、更高效的使用内存,将物理内存进行映射,对应用程序屏敝了物理内存的具体细节。


为什么要进行内存映射?


首先认识一下进程的内存布局是怎样的,如下图:





当有进程发生时,linux会将PM(物理内存)中的某些内存映射为大小为4GB的VM(虚拟内存);让每个进程误以为自己占据所有的内存空间。

(当然这并不是真正意义上的内存,这4GB为寻址空间, 虚拟内存不考虑物理内存的大小和信息存放的实际位置,只规定进程中相互关联信息的相对位置


回到刚刚的问题,前面也提到是为了更好的使用内存,那到底是怎么回事。首先虚拟内存提供了庞大的地址可以使用,每个进程可以直接寻址而不受其他进程的影响,每个指令或数据单元都在这个虚拟内存中拥有确定的地址。因此简化了程序的编写和系统统一管理。


如图所示,进程可以访问的内存区域为0x0804 8000 -- 0xc000 0000;0xc000 0000以上1GB的内存为内核保留;进程可以访问的区域又分为几个部分。


stack(栈内存)是从0xc000 0000 向下增长的部分,栈(遵循后进先出的逻辑)会随着程序的运行而不断地发生变化,主要用来存储进程执行过程中所产生的局部变量,当有新的函数被调用时,就会立即在栈顶分配一帧内存,专门用来存放该函数内定义的局部变量包括所有的形参;当一个函数执行完毕返回后,它所占用的那部分内存会被立即释放。栈的大小是有限度的,一般为8MB,超过最大限度会产生栈溢出,导致程序崩溃。


heap(堆内存)是一块完全由用户控制的内存它是向上增长的,堆内存是是不设大小限制的,最大值取决于系统物理内存。由于堆内存由用户控制,之后再说说堆内存的操作。


数据段分为三部分,地址从高到低分别为.bss段、.data段、.rodata段:

.bss段专门用来存放未初始化的静态数据,它们将被初始化为0;.data段专门存放已经初始化的静态数据;.rodata段用来存放只读数据,即常量。


代码段用来存放用户程序的。



说明:静态数据指的是所有的全局变量,以及static型局部变量;静态数据在进程的整个生命周期存在,在进程退出之前,会一直占用内存。


在此借用一个例子说明

int a= 0; 全局初始化区char *p1; 全局未初始化区main(){int b; 栈char s[] = "abc"; 栈char *p2; 栈char *p3 = "123456"; 123456\0在常量区,p3在栈上。static int c =0; 全局(静态)初始化区p1 = (char *)malloc(10);p2 = (char *)malloc(20);分配得来得10和20字节的区域就在堆区。strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。}







原创粉丝点击