计算机底层知识之内存和磁盘的关系&数据压缩

1,181 阅读9分钟

强者是什么?
绝对意义来说,是强于大多数人。
相对意义来说,是强于昨天的自己。

大家好,我是柒八九

今天,我们继续计算机底层知识的探索。我们来谈谈关于内存和磁盘关系&数据压缩的相关知识点。

如果,想了解该系列的文章,可以参考我们已经发布的文章。如下是往期文章。

文章list

  1. 计算机底层知识之CPU
  2. 计算机底层知识之二进制
  3. 计算机底层知识之处理小数
  4. 计算机底层知识之内存

你能所学到的知识点

  1. 不读入内存就无法运行 推荐阅读指数 ⭐️⭐️⭐️⭐️
  2. 磁盘缓存 推荐阅读指数 ⭐️⭐️⭐️
  3. 虚拟内存 推荐阅读指数 ⭐️⭐️⭐️
  4. 节约内存的编程方式(DLL文件) 推荐阅读指数 ⭐️⭐️⭐️⭐️
  5. 磁盘的物理结构 推荐阅读指数 ⭐️⭐️⭐️⭐️
  6. 文件以字节位单位保存 推荐阅读指数 ⭐️⭐️⭐️⭐️
  7. RLE算法 推荐阅读指数 ⭐️⭐️⭐️⭐️
  8. 哈夫曼算法 推荐阅读指数 ⭐️⭐️⭐️⭐️
  9. 可逆压缩和非可逆压缩

好了,天不早了,干点正事哇。


在计算机的5大部件中,内存磁盘都被归类为存储部件。不过,利用电流来实现存储的内存,同利用磁效应来实现存储的磁盘,还是有差异的。

从存储容量来看

  • 内存是高速高价
  • 磁盘是低速廉价

不读入内存就无法运行

计算机中主要的存储部分是内存磁盘磁盘中存储的程序,必须要加载到内存后才能运行。在磁盘中保存的原始程序是无法直接运行的。这是因为,负责解析和运行程序内容的CPU,需要通过内部程序计数器来指定内存地址,然后才能读出程序

存储在磁盘中的程序需要读入到内存后才能运行


磁盘缓存

{磁盘缓存|Disk Cache}指的是把从磁盘中读出的数据存储到内存空间中的方式。这样一来,当接下来需要读取同一数据时,就不用通过实际的磁盘,而是从磁盘缓存中把内容读出。

使用磁盘缓存可以大大改善磁盘数据的访问速度

低速设备的数据保存到高速设备中,需要时可以直接将其从高速设备中读出,这种缓存的方式在其他情况下也会用到。

其中一个实例就是在Web浏览器中的使用。由于Web浏览器是通过网络来获取远程Web服务器的数据并将其显示出来的。因此,在显示较大的图片等文件时,会花费不少时间。于是,Web浏览器就可以把获取的数据暂时保存在磁盘中,然后在需要时再显示磁盘中的数据。也就是,把低速的网络数据保存到相对高速的磁盘中


虚拟内存

{虚拟内存|Virtual Memory}是指把磁盘的一部分作为假想的内存来使用。这与磁盘缓存是假想的磁盘实际上是内存)相对,虚拟内存是假想的内存实际上是磁盘)。

通过借助虚拟内存,在内存不足时也可以运行程序。为了实现虚拟内存,就必须把实际内存(也可称为物理内存)的内容,和磁盘上的虚拟内存的内容进行部分置换,并同时运行程序。

虚拟内存的方法有分页式分段式两种。

Windows采用的是分页式。该方式是指,把运行的程序按照一定大小的{页|Page}进行分割,并以为单位在内存和磁盘间置换

在分页式中,把磁盘的内容读出到内存称为Page In,把内存的内容写入磁盘称为Page Out

为了实现虚拟内存功能,Windows磁盘上提供了虚拟内存用的{页文件|Page File}。该文件由Windows自动做成和管理。


节约内存的编程方式(DLL文件)

DLL(Dynamic Link Library)文件,是在程序运行时可以动态加载Library(函数和数据的集合)的文件。并且,多个应用可以共有同一个DLL文件。所以,通过共有同一个DLL文件可以达到节约内存的效果

假设我们编写了一个具有某些处理功能的函数MyFunc(),应用A和应用B都会使用这个函数。如果函数MyFunc()是独立的DLL文件,由于同一个DLL文件的内容在运行时可以被多个应用共有,因此内存中存在的函数MyFunc()的程序就只有一个。

Windows操作系统本身也是多个DLL文件的集合体。

DLL文件还有一个优点:在不变更可执行文件的情况下,只通过升级DLL文件就可以更新。


磁盘的物理结构

磁盘的物理结构是指磁盘存储数据的形式

磁盘是通过把其物理表面划分成多个空间来使用的。

划分的方式有扇区方式可变长方式两种。

  1. 扇区方式是指将磁盘划分为固定长度的空间
  2. 可变长方式是指把磁盘划分为长度可变的空间

Windows计算机所使用的硬盘,采用的都是扇区方式

扇区方式中,把磁盘表面分成若干个同心圆的空间就是磁道,把磁道按照固定大小(能存储的数据长度相同)划分而成的空间就是扇区

扇区是对磁盘进行物理读写的最小单位,一般一个扇区是512字节

不过,Windows逻辑方面软件方面)对磁盘就进行读写的单位是扇区的整数倍。根据磁盘容量的不同,1簇可以是512字节(1簇=1扇区)、1KB(1簇=2扇区)、2KB、4KB等。

不同的文件是不能存储在同一簇中的,否则就会导致只有一方的文件不能被删除


文件以字节位单位保存

文件是将数据存储在磁盘等存储媒介中的一种形式。程序文件中存储数据的单位是字节。文件的大小之所以用xxKBxxMB等来表示,就是因为文件是以字节(B = Byte)为单位来存储的。

文件就是字节数据的集合

用1字节(=8位)表示的字节数据有256种,用二进制数来表示的话,其范围就是00000000~11111111

  • 如果文件中存储的数据是文字,那么该文件就是文本文件
  • 如果是图形,那么该文件就是图像文件

在任何情况下,文件中的字节数据都是连续存储的。


RLE算法

我们来尝试对存储着AAAAAABBCDDEEEEEF这17个半角字符的文本文件进行压缩。

由于半角字母中,1个字符是作为1个字节的数据被保存在文件中的。因此,上述文件的大小就是17个字节。

我们可以采用将文件的内容用字符 × 重复次数这样的表现方式来压缩。所以,AAAAAABBCDDEEEEEF就可以用A6B2C1D2E5F1来表示。而A6B2C1D2E5F1是12个字符,那么对应的文本文件就变成了12字节。

12字节÷17字节 ≈70%。也就是采用上述的方式,使得文件压缩到原来大小的70%

把文件内容用数据 × 重复次数的形式来表示的压缩方法称为RLE(Run Length Encoding,行程长度编码)算法

RLE算法的缺点

然而在实际的文本文件中,同样字符多次重复出现的情况并不多见。虽然针对相同数据经常连续出现的图像、文件等,RLE算法可以发挥不错,但是它并不适合文本文件的压缩。


哈夫曼算法

哈夫曼算法是哈夫曼与1952年提出来的压缩算法。

针对,哈夫曼算法,首先要抛弃半角英文数字的1个字符是1个字节(8位)的数据这一概念。

文本文件是由不同类型的字符组合而成的,而且不同的字符出现的次数也是不同的。例如,在某一个文本文件中,A出现了100次,Q出现了3次。

哈夫曼算法的关键就在于多次出现的数据用小于8位的字节数来表示,不常用的数据则用超过8位的字节数来表示

AQ都用8位来表示时,原文件的大小就是100次 × 8位 + 3次 × 8位 = 824位,而假设A用2位,Q用10位表示,压缩后的大小就是100次 × 2位 + 3次 × 10位 = 230位

不过,有一点需要注意,

不管是不满8位的数据,还是超过8位的数据,最终都要以8位为单位保存到文件中

这是因为磁盘是以字节(8位)为单位来保存数据的。

用二叉树实现哈夫曼编码

哈夫曼算法是指,为各压缩对象文件分别构造最佳的编码体系,并以该编码体系为基础来进行压缩。因此,用什么样的编码(哈夫曼编码)对数据进行分割,就要由各个文件而定。

用哈夫曼算法压缩过的文件中,存储着哈夫曼编码信息和压缩过的数据。

在哈夫曼算法中,通过借助哈夫曼树构造编码体系,即使在不使用字符区分符号的情况下,也可以构建能够明确进行区分的编码体系。也就是说,利用哈夫曼树后,就算表示各字符的数据位数不同,也能够做成明确区分的编码。

制作哈夫曼树

自然界的树是从根开始生枝长叶,而哈夫曼树是从叶生枝,然后再生根

哈夫曼算法能够大幅度提升压缩比率

使用哈夫曼树后,出现频率越高的数据所占用的数据位数就越少,而且数据的区分也可以很清晰的实现。


可逆压缩和非可逆压缩

  • 可逆压缩:能还原到压缩前状态的压缩
  • 非可逆压缩:无法还原到压缩前状态的压缩


后记

分享是一种态度

参考资料:《程序是怎样跑起来的》

全文完,既然看到这里了,如果觉得不错,随手点个赞和“在看”吧。