强者是什么?
从绝对意义来说,是强于大多数人。
从相对意义来说,是强于昨天的自己。
大家好,我是柒八九。
今天,我们继续计算机底层知识的探索。我们来谈谈关于内存和磁盘关系&数据压缩的相关知识点。
如果,想了解该系列的文章,可以参考我们已经发布的文章。如下是往期文章。
文章list
你能所学到的知识点
- 不读入内存就无法运行 推荐阅读指数 ⭐️⭐️⭐️⭐️
- 磁盘缓存 推荐阅读指数 ⭐️⭐️⭐️
- 虚拟内存 推荐阅读指数 ⭐️⭐️⭐️
- 节约内存的编程方式(DLL文件) 推荐阅读指数 ⭐️⭐️⭐️⭐️
- 磁盘的物理结构 推荐阅读指数 ⭐️⭐️⭐️⭐️
- 文件以字节位单位保存 推荐阅读指数 ⭐️⭐️⭐️⭐️
- RLE算法 推荐阅读指数 ⭐️⭐️⭐️⭐️
- 哈夫曼算法 推荐阅读指数 ⭐️⭐️⭐️⭐️
- 可逆压缩和非可逆压缩
好了,天不早了,干点正事哇。
在计算机的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文件
就可以更新。
磁盘的物理结构
磁盘的物理结构是指磁盘存储数据的形式。
磁盘是通过把其物理表面划分成多个空间来使用的。
划分的方式有扇区方式和可变长方式两种。
- 扇区方式是指将磁盘划分为固定长度的空间
- 可变长方式是指把磁盘划分为长度可变的空间
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位)为单位来保存数据的。
用二叉树实现哈夫曼编码
哈夫曼算法是指,为各压缩对象文件分别构造最佳的编码体系,并以该编码体系为基础来进行压缩。因此,用什么样的编码(哈夫曼编码
)对数据进行分割,就要由各个文件而定。
用哈夫曼算法压缩过的文件中,存储着哈夫曼编码信息和压缩过的数据。
在哈夫曼算法中,通过借助哈夫曼树构造编码体系,即使在不使用字符区分符号的情况下,也可以构建能够明确进行区分的编码体系。也就是说,利用哈夫曼树后,就算表示各字符的数据位数不同,也能够做成明确区分的编码。
制作哈夫曼树
自然界的树是从根开始生枝长叶,而哈夫曼树是从叶生枝,然后再生根。
哈夫曼算法能够大幅度提升压缩比率
使用哈夫曼树后,出现频率越高的数据所占用的数据位数就越少,而且数据的区分也可以很清晰的实现。
可逆压缩和非可逆压缩
- 可逆压缩:能还原到压缩前状态的压缩
- 非可逆压缩:无法还原到压缩前状态的压缩
后记
分享是一种态度。
参考资料:《程序是怎样跑起来的》
全文完,既然看到这里了,如果觉得不错,随手点个赞和“在看”吧。