计算机的硬件设备
计算机的硬件设备中,有三个部件最为关键,它们分别是中央处理器CPU、内存和I/O控制芯片。
系统软件
系统软件可以分成两块,一块是平台性的,比如操作系统内核、驱动程序、运行库和数以千计的系统工具;另外一块是用于程序开发的,比如编译器、汇编器、链接器等开发工具和开发库。
计算机软件体系结构
操作系统发展史
1.在计算机发展早期,CPU资源十分昂贵,如果一个CPU只能运行一个程序,那么当程序读写磁盘(当时可能是磁带)时,CPU就空闲下来了,这在当时简直就是暴殄天物。于是人们很快编写了一个监控程序,当某个程序暂时无须使用CPU时,监控程序就把另外的正在等待CPU资源的程序启动,使得CPU能够充分地利用起来。这种被称为多道程序
(Multiprogramming)。
2.经过稍微改进,程序运行模式变成了一种协作的模式,即每个程序运行一段时间以后都主动让出CPU给其他程序,使得一段时间内每个程序都有机会运行一小段时间。这对于一些交互式的任务尤为重要,比如点击一下鼠标或按下一个键盘按键后,程序所要处理的任务可能并不多,但是它需要尽快地被处理,使得用户能够立即看到效果。这种程序协作模式叫做分时系统
(Time-Sharing System)。这时候的监控程序已经比多道程序要复杂多了,完整的操作系统雏形已经逐渐形成了。
3.多任务(Multi-tasking)系统
,操作系统接管了所有的硬件资源,并且本身运行在一个受硬件保护的级别。所有的应用程序都以进程(Process)的方式运行在比操作系统权限更低的级别,每个进程都有自己独立的地址空间,使得进程之间的地址空间相互隔离。CPU由操作系统统一进行分配,每个进程根据进程优先级的高低都有机会得到CPU,但是,如果运行时间超出了一定的时间,操作系统会暂停该进程,将CPU资源分配给其他等待运行的进程。这种CPU的分配方式即所谓的抢占式(Preemptive),操作系统可以强制剥夺CPU资源并且分配给它认为目前最需要的进程。如果操作系统分配给每个进程的时间都很短,即CPU在多个进程间快速地切换,从而造成了很多进程都在同时运行的假象。
进程与虚拟地址
进程是操作系统对一个正在运行的程序的一种抽象。在一个系统上可以同时运行多个进程,而每个进程都好像在独占地使用硬件。而并发运行,则是说一个进程的指令和另一个进程的指令是交错执行的。
无论是在单核还是多核系统中,一个 CPU 看上去都像是在并发地执行多个
进程,这是通过处理器在进程间切换来实现的。操作系统实现这种交错执行的机制称为上下文切换
。
操作系统保持跟踪进程运行所需的所有状态信息。这种状态,也就是上下文,包括许多信息,比如 PC 和寄存器文件的当前值,以及主存的内容。在任何一个时刻,单处理器系统都只能执行一个进程的代码。当操作系统决定要把控制权从当前进程转移到某个新进程时,就会进行上下文切换,即保存当前进程的上下文、恢复新进程的上下文,然后将控制权传递到新进程。新进程就会从它上次停止的地方开始。
如图所示,从一个进程到另一个进程的转换是由操作系统内核 (kernel) 管理的。内核是操作系统代码常驻主存的部分。当应用程序需要操作系统的某些操作时,比如读写文件,它就执行一条特殊的系统调用 (system call)指令,将控制权传递给内核。然后内核执行被请求的操作并返回应用程序。注意,内核不是一个独立的进程。相反,它是系统管理全部进程所用代码和数据结构的集合。
32位系统下每个进程都会分配4G的虚拟内存空间,而其实所有进程都共享着同一物理内存,每个进程只把自己目前需要的虚拟内存空间映射并存储到物理内存上。每次访问内存空间的某个地址,都需要把地址翻译为实际物理内存地址。
进程持有的虚拟地址会通过 CPU 芯片中的内存管理单元(MMU)
的映射关系,来转换变成物理地址,然后再通过物理地址访问内存。地址的映射,也就是页表的建立、映射过程。页表就是用来记录进程中哪些内存地址上的数据在物理内存上以及它们所在的位置的一个结构。每个进程都有一个页表,当进程需要访问某个虚拟地址时,就会去访问页表,页表实现从页号到物理块号的地址映射。存储在硬盘上的可执行程序被操作系统装载为进程,放入虚拟内存空间
。当需要访问内存空间的某个地址时,再通过MMU实现虚拟内存对物理地址的映射,达到访问物理地址的目的。
分页
分页是把整个虚拟和物理内存空间
切成一段段固定尺寸的大小。这样一个连续并且尺寸固定的内存空间,我们叫页(Page)。在 Linux 下,每一页的大小为 4KB。
虚拟地址与物理地址之间通过页表来映射,如下图:
分页的方式使得我们在加载程序的时候,不再需要一次性都把程序加载到物理内存中。我们完全可以在进行虚拟内存和物理内存的页之间的映射之后,并不是真的把页加载到物理内存里,而是只有在程序运行中,需要用到对应虚拟内存页里面的指令和数据时,再加载到物理内存里面去。
页错误
top命令中VIRT、RES和SHR
下面以下图为例对VIRT、RES和SHR进行解释,
ⅥRT表示的是进程虚拟内存空间大小。对应到上图中的进程A来说就是A1、A2、A3、A4以及灰色部分所有空间的总和.也就是说VIRT包含了在已经映射到物理内存空间的部分和尚未映射到物理内存空间的部分和。
RES的含义。指进程虚拟內存空间中已经映射到物理內存空间的那部分的大小。对应到上图中的进程A来说就是A1、A2、A3以及A4几个部分空间的总和。所以说,看进程在运行过程中占了多少内存应该看RES的值而不是VIRT的值。
SHR的含义。SHR是 share(共享)的缩写,它表示的是进程占用的共享内存大小。在上图中我们看到进程A虚拟内存空间中的A4和进程B虚拟内存空间中的B3都映射到了物理内存空间的A4/B3。
我们写的程序会依赖于很多外部的动态库(.so),比如libc.so、libd.so等等。这些动态库在内存中仅仅会保存/映射一份,如果某个进程运行时需要这个动态库,那么动态加载器会将这块内存映到对应进程的虚拟内存空间中。多个进程之间通过共享内存的方式相互通信也会出现这样的凊况。这么一来,就会出现不同进程的虚拟内存空间会映射到相同的物理内存空间。这部分物理内存空间其实是被多个进程所共享的,所以我们将他们称为共享内存,用SHR来表示。某个进程占用的内存除了和别的进程共享的内存之外就是自己的独占内存了。所以要计算进程独占内存的大小只要用RES的值减去SHR值即可 。
进程的smaps文件
在/proc目录下有以PID命名的文件夹:
cd到对应的文件中,可以看到smaps文档。
参考链接:
https://blog.csdn.net/qq_41687938/article/details/120479067
https://zhuanlan.zhihu.com/p/451736494