数据的存储
计算机中数据的存储可以通过有三种,他们方式分别是:
寄存器
内存
磁盘
他们的特点用一个表格来表示便一目了然
介质 特点
寄存器 CPU 内部的存储器,读写速度最快,容量最少,成本最高
内存 读写速度一般快,容量一般多(以 MB 或 GB 为单位),成本一般高
磁盘 读写速度最慢,容量最大(企业级磁盘以 GB 或 TB 为单位),成本最低
,我简单讲了下内存的一些知识,但是我没有说计算机为什么要使用内存这种东东,这之后我查阅了一下资料,也做了一些功课,这里就结合我自己的理解简单讲一下内存和磁盘的区别。
内存之所以叫内存,不是因为它放在计算机的内部,而是因为冯诺依曼体系结构决定了他叫内存,这话怎么理解呢?
冯诺依曼把计算机组成描述成下图所示的及结构:
他把计算机分成了 存储器,控制器,运算器,输入设备 和 输出设备 这 5 个组成部分,这五部分虽然不能与现代计算机的组成一一对应上,但是大体上还是相差无几的。比如 CPU 就相当于控制器和运算器,而 内存 就相当于存储器了。那为什么不说磁盘(硬盘或其他外部存储设备)是存储器呢?
在冯诺依曼体系结构中,控制器和运算器是可以直接对存储器进行读写的,CPU 会有相应的指令来读写存储器,那么符合这一条件的就只有内存和寄存器了。寄存器自然不用说,它是集成在 CPU 内部的。而像硬盘,闪存,U盘等等之类的磁盘的读写操作是要靠 IO指令 来操作的,且不管什么是 IO 指令,总之磁盘是不可以直接与 CPU 进行数据交换的,你想跟CPU通信,就得通过 IO 指令来做。那么,在 CPU 看来,这些磁盘的性质其实是跟我们的键盘鼠标网卡等输入输出设备没有本质的差别的。我们平时可能也会把磁盘说成存储器,那是因为磁盘是一个带有存储功能的 IO 设备,它与冯诺依曼体系中所说的存储器其实是两个不同的概念。
所以计算机需要内存这种东西,内存和外存(磁盘)也不是根据其在计算机的位置来区分的,而是根据 CPU 是如何读写这些设备来区分的。
磁盘缓存
磁盘缓存通俗的说就是操作系统在内存中划分出一块区域来,供 CPU 快速的读取数据来用的。了解磁盘缓存,首先要了解 存储式计算机 的含义。
冯诺依曼体系结构定义了现代计算机都是存储式计算机。所谓存储式计算机就是说我们的程序都是存储在计算机磁盘中的某个位置的,当要运行此程序的时候,程序文件会事先被加载到存储器中去,计算机能够自动连续的完成程序的执行,程序执行的结果也被存放在存储器中。程序运行所需要的信息以及结果的保存都是通过输入输出设备来完成。
大家都知道,磁盘的 IO 效率是非常低的,如果每次执行相同的程序都需要重新从磁盘加载程序文件就会拖慢整个计算机的运行速度。所以 磁盘缓存 就出现了。磁盘缓存又分为 读缓存 和 写缓存,读缓存就是指操作系统将已读取的程序文件数据,在内存较为空闲的时候留在内存的某一块空间中(我们同常称之为内存池),当下次再需要这些数据的时候,就不用再从磁盘加载了,直接从内存读取,以提高运行速度。写缓存道理也是一样,将需要写入到磁盘的文件数据先保留在内存中,当缓存空间满了的时候,再一次性写入到磁盘中去,这样就减少了磁盘的实际读写次数,提高了速度。
与磁盘缓存类似的技术还有 CPU 的高速缓存,分为一级缓存(L1 Cache),二级缓存(L2 Cache),三级缓存(L3 Cache)。L1 和 L2 Cache 是集成在 CPU 上的,L3 Cache 有外置的也有内置的。高速缓存对应的就是内存了,是为了提高 CPU 对内存的 IO 效率。其细节本人也不了解了,就不瞎说啦。
虚拟内存
虚拟内存的出现是为了解决内存不够用的情况的。有时候我们的程序运行所需的内存会超过计算机的物理内存,这样程序就运行不了了,因为内存不够用了,这时就可以从硬盘划分一块区域来做为临时内存来使用,保证程序能够正常运行起来。但是 CPU 只认识内存,而不认识虚拟内存,所以就需要操作系统来管理虚拟内存和物理内存。
虚拟内存实现方式常用的主要有两种:
分页式
分段式
先说分段式,这种方式现在用的也极少了,它的主要思想就是将程序分成多个段或模块,比如负责 IO 的分成一段,负责计算的分一段(可能说法不对,但博主也想不出其他的了 O.O)……这样分出来有的分段就会放在虚拟内存中,当程序需要执行这一块的时候,物理内存中的分段会与虚拟内存中的分段置换,这样程序的执行就不会受到影响了。
分页式实现虚拟内存的方式现在用的最多,Windows系统内部就是使用分页式管理虚拟内存的。它的主要思想就是将程序按顺序分成多个页,比如每 4KB 分一页,这样分出来很多页就可以分别放在物理内存和虚拟内存中了。例如物理内存中存放的是 1,2,3 页,虚拟内存放的是 4,5,6 页,当 123 页执行完了,就将虚拟内存中的 456 页置换过来继续执行。这就是虚拟内存的原理了。
如何节约内存
从编程的角度来看,节约内存的编程方式是极为重要的,好的习惯可以提高我们编写的软件在计算机中运行的效率。
1. 从函数调用的角度
我们可以尽量的使用 动态链接库(DLL) 来实现函数共用,这样当程序每次使用相同的函数时就不用开辟新的内存了。可以有效的节约程序执行的时候内存的使用。
2. 被调用方清理栈
函数每次调用完其所用的栈空间是要被回收的,回收的指令就是在结尾加上 add esp, 8,如果在调用方使用这样的指令来回收栈空间,势必会造成很多的内存浪费,因为如果调用方多次调用一个函数,这用的一行指令就需要写多次。如果我们在被调用方的结尾加上 add esp, 8,那么这行指令就只需要写一次了。从而有效的节省了内存。
当然还有其他方式,比如数据压缩什么的就不一一说了。