Linux虚拟内存空间分布

平常总说cpu的位数,其实说的是cpu一次能运算的最长整数的宽度,既ALU(算术逻辑单元)的宽度。
cpu的位数也是数据总线的条数
数据总线:数据线的总和,数据线就是cpu与内存进行数据传递的通道,一条数据线,一次可以传送1位二进制数,8条数据线一次就可以传8位(1个字节)
地址总线:CPU是通过地址总线来指定存储单元的,地址总线决定了cpu能访问的最大内存大小,比如,10位的地址线能访问的内存为1024位(1B)二进制数据
Linux虚拟内存空间分布_第1张图片
操作系统为了屏蔽I/O底层的差异,创建了VFS(虚拟文件系统),为了屏蔽I/O层与内存之间的差异,产生了虚拟内存。为了屏蔽cpu与内存之间的差异,创建了进程。每个程序运行起来都会拥有一个自己的虚拟地址空间,32位cpu的操作系统,其地址线也为32位,所以虚拟地址空间为2^32 -1= 4G
一个进程在运行时不可能会用如此大的虚拟地址空间,它们只会用到其中的一部分,而且并不一定连成一片,可能会被分割成几块,每一块连续的虚拟内存块被称为虚拟内存段。
Linux虚拟内存空间布局如下:
Linux虚拟内存空间分布_第2张图片
.reserve(预留)段
一共占用128M,属于预留空间,进程是禁止访问的

.text(代码段)
可执行文件加载到内存中的只有数据和指令之分,而指令被存放在.text段中,一般是共享的,编译时确定,只读,不允许修改

.data
存放在编译阶段(而非运行时)就能确定的数据,可读可写。也就是通常所说的静态存储区,赋了初值的全局变量和赋初值的静态变量存放在这个区域,常量也存放在这个区域

.bss段
通常用来存放程序中未初始化以及初始化为0的全局/静态变量的一块内存区域,在程序载入时由内核清0

.heap(堆)
用于存放进程运行时动态分配的内存,可动态扩张或缩减,这块内存由程序员自己管理,通过malloc/new可以申请内存,free/delete用来释放内存,heap的地址从低向高扩展,是不连续的空间

.stack(栈)
记录函数调用过程相关的维护性信息,栈的地址从高地址向低地址扩展,是连续的内存区域

共享库(libc.so)
静态库和动态库的区别:
(1)、不同操作系统下后缀不一样

             windows    linux
静态库         .lib       .a
动态/共享库     .dll       .so

(2)、加载方法的时间点不同
*.a 在程序生成链接的时候已经包含(拷贝)进来了
*.so 程序在运行的时候才加载使用

(3)静态库把包含调用函数的库是一次性全部加载进去的,动态库是在运行的时候,把用到的函数的定义加载进去,所以包含静态库的程序所以用静态库编译的文件比较大,如果静态库改变了,程序得重新编译,相反的,动态库编译的可执行文件较小,但.so改变了,不影响程序,动态库的开发很方便

(4)程序对静态库没有依赖性,对动态库有依赖性。

cat命令可以查看进程的虚拟地址空间布局
cat /proc/pid/maps
该输出命令一共有六列,分别为:
虚拟内存开始地址-结束地址、访问权限(r读-w写-x可执行-s共享-p私有) 、偏移量 、主设备号:次设备号、映像文件i节点 、映像文件路径

Linux虚拟内存空间分布_第3张图片

你可能感兴趣的:(Linux)