多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
本章主要介绍程序执行过程中操作系统、CPU都干了什么 # 运行前 程序在运行前,只是在硬盘上待着,此时就是一堆**二进制代码**而已,没有任何作用。 程序只有进入了内存才能运行,但是要进入内存,则需要服从**操作系统**的调度。 一个程序在运行的时候可能需要很大的空间,比如3G,但是操作系统不可能为每个程序都分配那么大,因为同时加载入内存的程序可能很多。 所以操作系统想了个办法,它和CPU一起“欺骗”了程序,它可以把硬盘的部分空间当作内存展示给程序,这就是**虚拟内存技术**,这种欺骗手段能实现的原因在于,程序的局部性原理,也就是程序不会同时运行所有的代码。 **虚拟内存**是一种内存管理技术,使得应用程序认为它拥有连续的可用的内存。 实际上可能并不是这样,它通常是被分隔成多个物理内存碎片,还有可能暂时存储在外部磁盘存储器上, ![image.png](http://upload-images.jianshu.io/upload_images/1323506-0778282632c5a541.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 这种做法最核心的问题就在于**调度**。我们可以把程序切分成若干块,也就是**页面**,然后分页装入内存中。这样,之后暂时用不到的页面就可以置换到硬盘上呢。 ![image.png](http://upload-images.jianshu.io/upload_images/1323506-58daa780e601af9b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![image.png](http://upload-images.jianshu.io/upload_images/1323506-78999fabd1743f03.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ## 装载 在程序运行之前,操作系统会进行程序的**装载**,也就是创建一个**进程结构**,它会有自己的一套虚拟地址、页表等结构。 但是装载器不会把代码装载到物理内存中,而是用一个**页表**把代码在硬盘上的位置记录下来,只有在真正运行的时候才会加载到内存里面。 最后,装载器会找到程序的入口地址,执行的时候,从入口地址开始读第一条指令。 # 运行 下载程序虽然还在硬盘里面,但是操作系统已经建立了一个**进程**,它有一套自己的虚拟地址、页表等高级数据结构。 操作系统进行进程的调度,当轮到这个进程来的时候,才从装载器返回的入口点开始执行。 CPU从程序入口处取出指令,但是这是一个虚拟地址,需要转换为物理地址。那么怎么转换呢?CPU会去查看**页表**,可以这个页表现在还指向的是**硬盘中的地址**,所以CPU会执行**缺页中断处理程序** 最后CPU会从硬盘里面把代码加载入内存,之后CPU当然得把**页表**修改一下,这样才能反映数据已经进入内存呢。 ![image.png](http://upload-images.jianshu.io/upload_images/1323506-6a2759fda0c0858b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 随着程序的执行,越来越多的数据和代码被加载到物理内存,而且这些加载到内存中的**页**不是连续的,他会安插在内存的不同位置去。 ![image.png](http://upload-images.jianshu.io/upload_images/1323506-022e0a01df99968f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 值得注意的是,在内存中的只是进程的一个实例而已,可以相当于程序的一个**化身**。 CPU会不断的读数据、写数据,时间片到了,就把进程挂起来,也就是说进程其实不是独占CPU的,只是因为进程切换得非常快,从人类的角度来看,以为程序在同时执行一样。 最后进程运行结束,内存中的数据会清理,覆盖。 ![image.png](http://upload-images.jianshu.io/upload_images/1323506-67d076eb7a5faa2d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) # 操作系统为什么要这么做 操作系统为什么要那么麻烦的搞出什么内存映射、虚拟内存来,还不是因为资源有限,内存就那么大,程序又那么多,为了让更多的程序运行起来,有效的利用内存和CPU,只能使用这种方法了。 # 参考 本文由[操作系统是个大骗子?](https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513894&idx=1&sn=3cf8faef41800f0dd52f84a0ae2d8065&chksm=80d67be5b7a1f2f31833dc71f8c67dc50e64b14bb5a25678155a7b39927b63db7c17510793d0&scene=21#wechat_redirect)改编过来的