文章目录
- malloc及4G虚拟空间分布
- 1.malloc
- 2.32位操作系统进程的4G虚拟空间分布
- 1) 代码区(Text egment):
- 2) 全局初始化数据区/静态数据区(Data Segment)
- 3) 未初始化数据区(BSS):
- 4) 堆区(heap):
- 5) 栈区(stack):
malloc及4G虚拟空间分布
1.malloc
1.进程在执行的过程中,malloc申请空间,不使用时,没有free就会出现内存泄漏;
如果进程结束了,那么所有向操作系统申请的内存都会被回放(释放);
2.申请1G或者更大空间,到底能不能成功?
如果当前的物理内存剩余空间够用,那么申请的空间肯定能成功;
如果物理内存不够,先看有没有虚拟内存,如果有,看虚拟内存加上物理内存能否满足申
请的空间大小;
sudo swapoff -a;关闭虚拟内存;
sudo swapon -a;开启虚拟内存;
3.父进程堆区申请的空间复制后,子进程也有一份.
也需要释放;
fork会把进程的上下文都复制一遍,如果是malloc申请的话,
内核会给子进程分配和父进程一样多的空间,父子进程都需要分别free;
2.32位操作系统进程的4G虚拟空间分布
1) 代码区(Text egment):
代码区指令根据程序设计流程依次执行,对于顺序指令,则只会执行一次(每个进程),如果反复,则需要使用跳转指令,如果进行递归,则需要借助栈来实现。
代码段: 代码段(code segment/textsegment )通常是指用来存放程序执行代码的一块内存区域。 这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序 在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
代码区的指令中包括操作码和要操作的对象(或对象地址引用)。如果是立即数(即具体的 数值,如5),将直接包含在代码中;如果是局部数据,将在栈区分配空间,然后引用该数据地址;如果是BSS区和数据区 在代码中同样将引用该数据地址。另外,代码段还规划了局部数据所申请的内存空间信息。
2) 全局初始化数据区/静态数据区(Data Segment)
只初始化一次。
数据段: 数据段(data segment )通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。
data段中的静态数据区存放的是程序中已初始化的全局变量、静态变量和常量。
3) 未初始化数据区(BSS):
在运行时改变其值。
BSS 段: BSS 段(bss segment )通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS 是英文Block Started by Symbol 的简称。
BSS 段属于静态内存分配, 即程序一开始就将其清零了。一般在初始化时BSS段部分将会清零。
4) 堆区(heap):
用于动态内存分配。堆在内存中位于bss区和栈区之间。一般由程序员分配和释放,若程序员不释放,程序结束时有可能由OS回收。
堆(heap): 堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc 等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free 等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)。
在将应用程序加载到内存空间执行时,操作系统负责代码段、数据段和BSS段的加载, 并将在内存中为这些段分配空间。栈段亦由操作系统分配和管理,而不需要程序员显示地管理;堆段由程序员自己管理,即显式地申请和释放空间。
5) 栈区(stack):
由编译器自动分配释放,存放函数的参数值、局部变量的值等。
存放函数的参数值、 局部变量的值,以及在进行任务切换时存放当前任务的上下文内容。其操作方式类似于数据结构中的栈。 每当一个函数被调用,该函数返回地址和一些关于调用的信息,比如某些寄存器的内容,被存储到栈区。 然后这个被调用的函数再为它的自动变量和临时变量在栈区上分配空间, 这就是C实现函数递归调用的方法。每执行一次递归函数调用,一个新的栈框架就会被使用, 这样这个新实例栈里的变量就不会和该函数的另一个实例栈里面的变量混淆。
栈(stack) :栈又称堆栈, 是用户存放程序临时创建的局部变量,也就是说我们函数括弧"{}"中定义的变量 (但不包括static 声明的变量,static 意味着在数据段中存放变量)。除此以外,在函数被调用时, 其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放 回栈中。由于栈的先进先出特点, 所以栈特别方便用来保存/ 恢复调用现场。
从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。