第一章笔记传送门 👉 点击这里
第二章笔记传送门 👉 点击这里
第三章笔记传送门 👉 点击这里
第四章笔记传送门 👉 点击这里
第五章笔记传送门 👉 点击这里
第六章笔记传送门 👉 点击这里
第七章笔记传送门 👉 点击这里
第八章笔记传送门 👉 点击这里
第九章笔记传送门 👉 点击这里
第五章:内存和磁盘的亲密关系
- 存储程序方式指的是什么
在存储装置中保存程序,并逐一运行的方式 - 通过使用内存来提高磁盘访问速度的机制称为什么
Disk Cache(磁盘缓存)(把从磁盘中读出来的数据存储在主存中,当该数据再次被读时,不是从磁盘而是直接从内存中高速读取) - 把磁盘的一部分作为假象内存来使用的机制称为什么
虚拟内存(Virtual Memory)(借助虚拟内存,哪怕时内存容量不足的计算机,也能运行很大的程序) - Windows中,在程序运行时,存储着可以动态加载调用的函数和数据的文件称为什么
DLL(DLL文件)(Dynamic Link Liabrary) - 在EXE程序文件中,静态加载函数的方式称为什么
静态链接 - 在Windows计算机中,一般磁盘一个扇区是多少字节
512字节(扇贝是磁盘保存数据的物理单位)
内存利用电流来实现存储,磁盘使用磁效应实现存储
通常内存高速高价,磁盘低速低价
5.1 不读入内存就无法运行
- 磁盘中存储的程序,必须加载到内存后才能运行
(CPU需要通过内部程序计数器来指定内存地址,然后才能读出程序,即使CPU能直接读出来并运行磁盘中保存的程序,但是这样速度会很慢)
5.2 磁盘缓存加快了磁盘访问速度
(把低速设备的数据保存在高速设备上,需要时可以直接将其从高速设备中读出,这种在其他情况下也会用到:例如在Web浏览器中使用,会把比如图片缓存在磁盘上)
5.3 虚拟内存把磁盘当作部分内存来使用
- 虚拟内存:把磁盘的一部分当作假想的内存来使用
- 借助虚拟内存,在内存不足时也可以运行程序。
(例如在只剩下5M内存空间情况下也能运行10M大小的程序(但是CPU只能执行加载到内存中的程序,虚拟内存虽说把磁盘作为内存的一部分来使用,但实际上正在运行的程序部分,在这个时间点上时必须存在在内存中的,也就是说,为了实现虚拟内存,就必须把实际内存的内容,和磁盘上的虚拟内存上的内容进行部分置换,并同时运行程序)) - Windows提供了虚拟内存机制作为操作系统。
- 虚拟内存方法有两种:分页式,分段式。Windows采用的是分页式。大小为4KB
(分页式是把运行的程序按照一定大小的页进行分割,并以页为单位在内存和磁盘间进行置换)(Page In:把磁盘内容读到内存)(Page Out:把内存内容读到磁盘)
(分段式虚拟内存是指:把要运行的程序分割成以处理集合及数据集合等为单位的段落,然后再以分割后的段落为单位在内存和磁盘之间进行数据置换) - 为了实现虚拟内存的功能,Windows在磁盘上提供了虚拟内存用的文件,页文件(page file)。该文件由Windows自动做成管理。文件的大小也就是虚拟内存的大小,通常是实际内存的相同程序至两倍程度。
(通过Windows控制面板可以查看或改变当前虚拟内存的设定)
5.4 节约内存的编程方法
- 虚拟内存确实能避免因内存不足导致的应用无法启动,不过由于低速的访问,整个过程会变得迟钝。硬盘访问灯亮着表示在进行Page In和Page Out。所以虚拟内存无法从根本上解决内存不足的问题。
- 解决办法:
一:加内存(花费高)
二:尽量把运行程序变小
具体做法:
- 通过DLL文件实现函数共有
DLL是在程序运行时可以动态加载Library(函数和数据的集合)的文件,且多个应用可以共有同一个DLL文件。通过共用同一个DLL文件就可以达到节约内存的效果
Windows操作系统本身也是多个DLL文件的集合。又是有时安装新应用时,DLL文件也会被追加。应用则会通过利用这些DLL文件的功能来运行。
DLL文件还有一个优点就是,在不变更EXE文件的情况下,只通过升级DLL文件就可以更新
可以参考这位老哥的博客:点击此处 - 通过调用_stdcall来减小程序文件的大小
(C语言特有的调用方式称为C调用。C语言之所以默认不使用_stdcall,是因为C语言所对应的函数的传入参数时可变的(可以设定任意参数),只有函数调用方才能知道到底有多少个参数,而在这种情况下,栈的清理作业便无法进行。不过在C语言中,如果函数的参数数量固定的话,指定_stdcall时没有任何问题的)
下面这张图片来自百度
- 栈清理处理:把不需要的数据从接收和传递函数的参数时使用的内存上的栈区域中清理出去。该命令不是程序记述的,而是在程序编译时由编译器自动附加到程序中的。编译器默认将该处理附加在函数的调用方。
- C语言中,函数的返回值是通过寄存器,而非栈,来返回的
- 32位CPU中,一次push可以存储4个字节的数据。上述程序使用了两次,故存储了8个字节的数据。通过call指令调用函数后,栈中的数据就不再需要了,于是这时就通过add,esp,8这个指令,使存储的数据不再需要了,使存储着栈数据的esp寄存器前进8位(设定为指向高8位字节地址),来进行数据清理。
- 栈请除处理,比起来调用方进行,在反复被调用的函数一方进行时,程序整体要小一些。这是使用的就是_stdcall,就可以把栈清理处理变为被调用函数一方进行,int MyFunc(int a, int b)部分写成int _stdcall MyFunc(int a, int b),进行编译后,add,esp,8同样的处理就会在函数MyFunc()一方执行。
- CPU中,栈中堆积的最高位的数据地址是保存在esp中的,连续运行两次pop指令,可以消除两个存储在栈中的4字节数据,而同样的功能也可以通过把esp的数值增加8来实现
5.5 磁盘的物理结构
- 磁盘的物理结构是指磁盘存储数的形式
- 磁盘通过把物理表面划分为多个空间来使用的
- 划分方式:扇区方式(划分成固定长度的空间),可变长方式(把磁盘划分为长度可变的空间)
- 磁道:扇区方式中,把磁盘表面分成若干个同心圆的空间
- 扇区:把磁道按照固定大小(能存储的数据长度相同)划分而成的空间就是扇区
是对磁盘进行读写的最小的单位 - Windows中使用的磁盘,一般一个扇区为512字节
不过在逻辑方面,对磁盘进行读一些的单位是扇区整数倍的簇。根据磁盘的容量不同,1簇可以是512(1扇区)字节,可以是1KB(2扇区),可以是2KB。。。磁盘的容量越大,簇的容量也越大。 - 在软盘中,1簇=512字节=一扇区,簇和扇区的大小是相等的。
- 不管是硬盘还是软盘,不同的文件时不能存储在同一个簇中的,否则就会导致只有一方的文件不能被删除。因此,不管多么小的文件,都会占用1簇的空间。这样,所有的文件都会栈用1簇的整数倍的磁盘空间。