首先我们有这样一段代码?🚀?
我们写的代码不管是什么语言,无非就是产生指令和数据这两种东西,在内存中分别存放在不同的区域
首先,能称得上是计算机系统肯定要有?
CPU 内存 和 I/O
但是操作系统为了避免底层硬件的差异,使我们应用层的用户在使用的时候调用统一的接口,就像我们的open,不止可以打开文件,还可以打开字符设备等等
比如说为了屏蔽底层I/O的差异,我们基于I/O层,通过系统提供的VFS(虚拟文件系统)来屏蔽I/O层底层的所有差异
为了屏蔽内存和I/O的差异,也是资源分配的管理单位,我们有虚拟存储器,也就是虚拟内存
为了屏蔽CPU 内存 I/O的底层差异,也作为这三个部件资源调度的基本单位,操作系统给我们提供了一个概念,进程
进程,虚拟内存,虚拟文件系统也是我们操作系统内核离不开的三个重要部分
操作系统内核把底层的这些东西都屏蔽起来了,所以说如果有操作系统在,我们就不可能直接把写的代码生成的可执行文件直接存放进内存当中,他是直接加载到虚拟存储中的
那么虚拟内存多大呢??🚀?
在x86 32bit Linux内核下,也就是CPU是32位,我们知道CPU是运算数据的(在ALU算数逻辑单元里面(CPU的位数也就是ALU(算术逻辑单元)的宽度)),而数据又是从数据总线来的,所以说CPU的位数就是ALU的宽度也就是数据总线的条数
补充:平时我们说CPU位数是32位,地址总线也是32位这只是32位CPU刚刚好就是这样,他的数据总线和地址总线都是32条的,确实并不是都是这样的。比如16位CPU来说,数据总线16条,地址总线20条,对于8位的CPU数据总线是8条,地址总线是16条。所以说不要认为CPU的位数就是地址总线的条数,但是可以认为CPU的位数是数据总线的条数哈。
然后回到虚拟内存
那肯定是虚拟的,不存在的,是人们假想的,是逻辑上抽象出来的,当我们每生成一个可执行文件在他运行的时候,操作系统都会给他提供一个虚拟内存
虚拟内存(虚拟地址空间)有多大呢?
其实是与CPU的位数有关,如果CPU的位数是32位,那么他的大小就是2^32(4G),也可以理解为CPU的寻址能力。这4G是每一个程序运行起来都会有的,注意是虚拟的。
那虚拟地址空间是怎么布局的呢??🚀?
PS:如果堆还没有开辟,操作系统给了我们一个名词就是空洞,这是给堆预留的空间
text是存放指令的
数据段是存放数据的,包括data和bss?
在我们先前的程序中
(最下面的大括号也是在红框框哈)
其实很多人在写程序的时候都会有一个问题
我们都知道我们调用库函数要包含头文件,但是头文件里面只有声明又没有定义,那怎么程序就运行起来了呢?
当我们写出这样的程序的时候,其实只有他的声明,但是他的定义在哪里呢,有人就会说是在库里面,其实不是的,因为库是在磁盘的,但是我们在运行程序的时候是在内存,其实是在程序链接的时候链接的动态库,C语言是libc.so而C++是libc++.so,这个库也叫共享库
main函数的真面目(命令行参数和环境变量)?🚀?
总的来说?🚀?
在每一个进程运行的时候,系统都会给他分配一个与CPU位数有关的(4G的)虚拟地址空间,空间分成两部分,低3G是用户空间,是应用程序用户供程序执行的,高1G是内核空间,供内核代码来执行的。非常重要的一点,系统可以运行很多的进程,他们的用户空间都是独立的,但是内核空间都是共享的(因为只有一个系统)
PS:其实我们大家说的全局变量区其实是不准确的,因为并没有这个词,这是我们翻译过来的,可以说是text段(区)data段(区)和bss段(区)。
内核分区 16MB 892MB 128MB
第一部分DMA,直接内存访问,加快磁盘和内存交换数据用的(了解),在没有DMA之前,交换数据必须要从数据总线然后通过寄存器去交换,那是对CPU极大的浪费,有了DMA,比如我们加载一个文件进内存,就不用走寄存器了,比如我们打开一个文件涉及磁盘的数据进物理内存中,此时CPU就会空闲下来调度其他的进程。
第二部分是我们的常用部分
第三部分是高端内存
比如在我们32位Linux系统,映射高于1G的物理内存的时候,会用到高端内存。而64位机器用不到,因为其内核空间高达512G,而一般电脑8G都不错了。所以说HIGHMEM在32位机器上还是非常有必要的。