
前端小魔女
2022/11/02阅读:23主题:蔷薇紫
计算机底层知识之内存和磁盘的关系&数据压缩
❝强者是什么?
❞
从「绝对意义」来说,是强于大多数人。
从「相对意义」来说,是强于昨天的自己。
大家好,我是「柒八九」。
今天,我们继续「计算机底层知识」的探索。我们来谈谈关于「内存和磁盘关系」&「数据压缩」的相关知识点。
如果,想了解该系列的文章,可以参考我们已经发布的文章。如下是往期文章。
文章list
你能所学到的知识点
❝❞
不读入内存就无法运行 「推荐阅读指数」 ⭐️⭐️⭐️⭐️ 磁盘缓存 「推荐阅读指数」 ⭐️⭐️⭐️ 虚拟内存 「推荐阅读指数」 ⭐️⭐️⭐️ 节约内存的编程方式(DLL文件) 「推荐阅读指数」 ⭐️⭐️⭐️⭐️ 磁盘的物理结构 「推荐阅读指数」 ⭐️⭐️⭐️⭐️ 文件以字节位单位保存 「推荐阅读指数」 ⭐️⭐️⭐️⭐️ RLE算法 「推荐阅读指数」 ⭐️⭐️⭐️⭐️ 哈夫曼算法 「推荐阅读指数」 ⭐️⭐️⭐️⭐️ 可逆压缩和非可逆压缩
好了,天不早了,干点正事哇。
在计算机的5大部件中,「内存」和「磁盘」都被归类为「存储部件」。不过,利用「电流」来实现存储的内存,同利用「磁效应」来实现存储的磁盘,还是有差异的。
从存储容量来看
-
内存是「高速高价」 -
磁盘是「低速廉价」
不读入内存就无法运行
计算机中主要的存储部分是「内存」和「磁盘」。「磁盘中存储的程序,必须要加载到内存后才能运行。在磁盘中保存的原始程序是无法直接运行的」。这是因为,「负责解析和运行程序内容的CPU,需要通过内部程序计数器
来指定内存地址,然后才能读出程序」
❝存储在磁盘中的程序需要读入到内存后才能运行
❞

磁盘缓存
磁盘缓存指的是把从磁盘中读出的数据存储到「内存空间」中的方式。这样一来,当接下来需要读取「同一数据」时,就不用通过实际的磁盘,而是从磁盘缓存中把内容读出。
❝使用磁盘缓存可以大大改善磁盘数据的访问速度
❞

把「低速设备」的数据保存到「高速设备」中,需要时可以直接将其从高速设备中读出,这种「缓存」的方式在其他情况下也会用到。
其中一个实例就是在Web浏览器
中的使用。由于Web浏览器
是通过「网络」来获取「远程」Web服务器
的数据并将其显示出来的。因此,在显示较大的图片等文件时,会花费不少时间。于是,Web浏览器
就可以把获取的数据「暂时」保存在「磁盘」中,然后在需要时再显示磁盘中的数据。也就是,「把低速的网络数据保存到相对高速的磁盘中」。
虚拟内存
虚拟内存是指把「磁盘」的一部分作为「假想的内存」来使用。这与磁盘缓存是「假想的磁盘」(实际上是内存
)相对,虚拟内存是「假想的内存」(实际上是磁盘
)。
「通过借助虚拟内存,在内存不足时也可以运行程序」。为了实现虚拟内存,就必须把「实际内存」(也可称为「物理内存」)的内容,和磁盘上的虚拟内存的内容进行「部分置换」,并同时运行程序。
❝虚拟内存的方法有「分页式」和「分段式」两种。
❞
Windows
采用的是「分页式」。该方式是指,「把运行的程序按照一定大小的页进行分割,并以页
为单位在内存和磁盘间置换」。
在分页式中,把磁盘的内容读出到内存称为Page In
,把内存的内容写入磁盘称为Page Out
。

为了实现虚拟内存功能,Windows
在「磁盘」上提供了虚拟内存用的页文件。该文件由Windows
自动做成和管理。
节约内存的编程方式(DLL文件)
「DLL(Dynamic Link Library)文件」,是在程序「运行时」可以「动态」加载Library
(函数和数据的集合)的文件。并且,多个应用可以「共有同一个」DLL文件
。所以,「通过共有同一个DLL文件
可以达到节约内存的效果」。
假设我们编写了一个具有某些处理功能的函数MyFunc()
,应用A
和应用B
都会使用这个函数。如果函数MyFunc()
是独立的DLL文件
,由于同一个DLL文件
的内容在运行时可以被多个应用共有,因此内存中存在的函数MyFunc()
的程序就只有一个。

❝❞
Windows
的「操作系统」本身也是多个DLL文件
的集合体。
DLL文件
还有一个优点:在不变更可执行文件的情况下,只通过升级DLL文件
就可以更新。
磁盘的物理结构
「磁盘的物理结构是指磁盘存储数据的形式」。
❝磁盘是通过把其物理表面划分成多个空间来使用的。
❞
划分的方式有「扇区方式」和「可变长方式」两种。
-
「扇区方式」是指将磁盘划分为「固定长度」的空间 -
「可变长方式」是指把磁盘划分为「长度可变」的空间
Windows
计算机所使用的硬盘,采用的都是「扇区方式」。
扇区方式中,把磁盘表面分成若干个「同心圆的空间」就是「磁道」,把磁道按照「固定大小」(能存储的数据长度相同)划分而成的空间就是「扇区」。

❝扇区是对磁盘进行「物理读写」的最小单位,一般一个扇区是512字节
❞
不过,Windows
在「逻辑方面」(软件方面
)对磁盘就进行读写的单位是扇区的整数倍「簇」。根据磁盘容量的不同,1簇可以是512字节(1簇=1扇区)、1KB(1簇=2扇区)、2KB、4KB等。
❝「不同的文件是不能存储在同一簇中的」,否则就会导致只有一方的文件不能被删除
❞
文件以字节位单位保存
文件是将数据存储在磁盘等存储媒介中的一种形式。程序文件中存储数据的单位是「字节」。文件的大小之所以用xxKB
、xxMB
等来表示,就是因为文件是以字节(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位的字节数来表示」。
❞
当A
和Q
都用8位来表示时,原文件的大小就是100次 × 8位 + 3次 × 8位 = 824位
,而假设A
用2位,Q
用10位表示,压缩后的大小就是100次 × 2位 + 3次 × 10位 = 230位
。
不过,有一点需要注意,
❝不管是不满8位的数据,还是超过8位的数据,最终都要「以8位为单位保存到文件中」。
❞
这是因为磁盘是以字节(8位)为单位来保存数据的。

用二叉树实现哈夫曼编码
哈夫曼算法是指,为「各压缩对象文件」分别构造最佳的编码体系,并以该编码体系为基础来进行压缩。因此,用什么样的编码(哈夫曼编码
)对数据进行分割,就要由各个文件而定。
用哈夫曼算法压缩过的文件中,存储着哈夫曼编码信息和压缩过的数据。

在哈夫曼算法中,通过借助「哈夫曼树」构造编码体系,即使在不使用字符区分符号的情况下,也可以构建能够明确进行区分的编码体系。也就是说,利用哈夫曼树后,就算表示各字符的数据「位数」不同,也能够做成明确区分的编码。
制作哈夫曼树
自然界的树是从根开始生枝长叶,而哈夫曼树是「从叶生枝,然后再生根」。

哈夫曼算法能够大幅度提升压缩比率
使用哈夫曼树后,出现「频率越高的数据所占用的数据位数就越少」,而且数据的区分也可以很清晰的实现。
可逆压缩和非可逆压缩
-
「可逆压缩」:能还原到压缩前状态的压缩 -
「非可逆压缩」:无法还原到压缩前状态的压缩

后记
「分享是一种态度」。
参考资料:《程序是怎样跑起来的》
「全文完,既然看到这里了,如果觉得不错,随手点个赞和“在看”吧。」

作者介绍

前端小魔女
微信公众号:前端柒八九