一: 程序地址空间
1.1:栈
小辉:小黑,栈有多大啊?8M左右吗?
小黑:栈大小为8M的说法是错误的,
因为栈数的大小是可以配置的。
- 保存局部变量
- 在(centors 上大小约为8M)栈的大小可以配置(要看平台)
- 验证栈大小的小程序
#include<stdio.h>
int main(){
char arr[1024*1000*8]={0};
return 0;
}
- 栈的大小可以配置,不能答出具体数字
ulimit -a
查看所有 ulimit 的内容
ulimit -s 10240 (配置10M空间)
如果是小对象,并且需要频繁创建和销毁,推荐在栈上分配栈上空间内存更高效
1.2:共享内存区
- 1.动态库
- 2.共享内存机制
- 3.线程信息
1.3:堆
小辉:小黑,那堆有多大呢?
小黑:直接说堆的大小也是错误的,
堆的大小要看平台,说堆的大
小,要先说明是那种平台上。
32位平台下 :4G
64位下平台特别大
-
动态申请的空间
-
如果是大对象,必须在堆上分配
-
malloc/new 申请空间 , new 需要调用构造函数
1.4:数据段
全局变量/静态变量
1.5:代码段(只读)
存放二进制代码/字符串的字面常量
1.6:内存池
- 提前申请好一批内存,需要时直接拿来用
需要比较大的内存又需要频繁的申请和释放选用内存池比较合适
1.7:性能优化:先性能测试,再确定能否优化。
-
具体优化方向
-
缓存区
-
缓冲区
-
池
分页&虚拟地址空间
小黑:大家要注意在程序运行过程中我们
所看到的地址,是虚拟地址.虚拟地址
通过 页表 映射到物理地址上 才是
真真的内存奥
- (花名册)虚拟地址=》物理地址(虚拟地址和物理地址之间的映射关系)
#include<stdio.h>
#include<unistd.h>
int count=0;
int main(){
pid_t pid=fork();
if(pid>0){
printf("father:%d,%d,%p\n",getpid(),count,&count);
}else if(pid==0){
count=100;
printf("child:%d,%d,%p\n",getpid(),count,&count);
}
sleep(1);
return 0;
}
- 运行结果
虽然两者的虚拟地址是相同的,但是他们映射到物理地址的结果是不同的
- 我们发现,父子进程输出的地址是一致的,但是变量内容不一样!因此我们得出如下结论
- 变量内容不一样,所以父子进程输出的变量绝对不是同一个变量
- 但是地址是一样的,说明,该地址绝对不是物理地址
- 在Linux地址下,这种地址叫做虚拟地址
- 我们在用c/c++语言所看到的地址,全都是虚拟地址!物理地址,用户压根看不到,由操作系统统一管理
OS必须负责将虚拟地址转换成物理地址
-
上面的图说明:同一变量,地址相同,其实是虚拟地址相同,内容不同.其实是被映射到了不同的物理地址!
-
虚拟地址的好处
可以使程序与程序之间相互独立