【计算机组成原理】读书笔记第三期:内存和磁盘的关系

news2024/10/2 14:24:07

目录

写在开头

内存与磁盘的关系

基本关系

磁盘缓存

虚拟内存 

节约内存的编程方法

通过DLL文件实现函数共有

通过调用_stdcall来降低文件程序的大小

磁盘的物理结构 

结尾

写在开头

  本文继续阅读总结《程序是怎样跑起来的》这本书(作者:矢泽久雄)。前两篇博客介绍了这本书的阅读感受,并分别对第一章CPU、第四章内存相关的知识进行了总结。详情见:

【计算机组成原理】读书笔记第一期:对程序员来说CPU是什么-CSDN博客

【计算机组成原理】读书笔记第二期:使用有棱有角的内存_Bossfrank的博客-CSDN博客

  本文将介绍本书的第五章:内存与磁盘的亲密关系。主要介绍了内存与磁盘的相互关系节约内存的编程方法和磁盘的物理结构

内存与磁盘的关系

 本文内存主要指主内存,即存储CPU中运行的程序指令和数据的区域,磁盘主要指硬盘。从存储容量上看,内存是高速(读取速度上)高价(价格上),磁盘则是低速廉价

基本关系

  磁盘中存储的程序,必须要加载到内存中才能运行。在磁盘中保存的原始程序是不能直接运行的。原因:负责解析和运行程序内容的CPU,需要通过内部程序计数器来指定内存地址才能读出程序(详见第一章总结)。即使CPU可以直接读出并运行磁盘中保存的程序,由于磁盘读取速度慢,程序的运行速度也会降低。

  程序要加载到内存中才可运行(图5-1),这是理解内存和磁盘关系的基础。接下来介绍两种机制,分别是将内存空间暂时充当磁盘的磁盘缓存和将磁盘空间暂时充当内存的虚拟内存。 

磁盘缓存

  磁盘缓存(disk cache)是指把从磁盘中读出的数据存储到内存空间中的方式。通过这样的方式,当之后需要读取同一数据时,就不用再去读取访问速度缓慢的磁盘空间,而是直接从内存(即磁盘缓存)中把内容读出,使用磁盘缓存可以大幅度提高磁盘数据的访问速度。Windows提供了磁盘缓存机制,不过随着硬盘访问速度的大幅度改善,磁盘缓存的效果没有那么明显了。

虚拟内存 

  虚拟内存(virtual memory)是指把磁盘的一部分作为假想内存来使用。通过这一机制,当程序的大小略超过内存的剩余空间时,也可以运行程序。不过由于CPU只能执行加载到内存中的程序。虚拟内存虽说是把磁盘作为内存的一部分来使用,但实际上正在运行的程序部分,在这个时间点上是必须存在在内存中的。也就是说,为了实现虚拟内存,就必须把实际内存(也可称为物理内存)的内容,和磁盘上的虚拟内存的内容进行部分置换(swap),并同时运行程序。

  虚拟内存有分段式和分页式两种,介绍如下:

分段式虚拟内存:把要运行的程序分割成以处理集合及数据集合等为单位的段落,然后再以分割后的段落为单位在内存和磁盘之间进行数据置换。

分页式虚拟内存:在不考虑程序构造的情况下,把运行的程序按照一定大小的页(page)进行分割,并以页为单位在内存和磁盘间进行置换。

  在windows中,虚拟内存采用分页式。在分页式中,把磁盘的内容读出到内存称为Page In,把内存的内容写入磁盘称为Page Out。一般情况下,Windows 计算机的页的大小是4KB。也就是说,把大程序用4KB的页来进行切分,并以页为单位放入磁盘(虚拟内存)或内存中(图5-3)。 

 顺道一提,在Windows中的控制面板可以查看或变更当前虚拟内存(设置搜索”调整Windows的外观和性能“选择”高级“) 

做个对比:

磁盘缓存虚拟内存
定义将近期从磁盘中读出的数据存储到内存空间中。把磁盘的一部分作为假想的内存来使用。
目的提高磁盘读取速度。在内存不足时也能运行程序。
本质内存(假想的磁盘)磁盘(假想的内存)

节约内存的编程方法

  虚拟内存是无法从根本上解决内存不足的问题。这是因为使用虚拟内存时发生的Page In 和Page Out 往往伴随着低速的磁盘访问,因此在这个过程中应用的运行会变得迟钝起来,同时这个机制并不能无限扩展内存空间(实际内存的总空间大小不变),因此我们在编程时还是要想办法节约内存。

通过DLL文件实现函数共有

  DLL(Dynamic Link Library)文件:动态链接库文件,指在程序运行时可以动态加载库(函数和数据的的集合)的文件。多个应用可以共有同一个DLL 文件。而通过共有同一个DLL 文件则可以达到节约内存的效果。要想了解动态链接库,先要了解静态链接:

静态链接:在实际开发中,不可能将所有代码放在一个源文件中,所以会出现多个源文件,而且多个源文件之间不是独立的,而会存在多种依赖关系,如一个源文件可能要调用另一个源文件中定义的函数,但是每个源文件都是独立编译的,即每个.c文件会形成一个.o文件,为了满足前面说的依赖关系,则需要将这些源文件产生的目标文件进行链接,从而形成一个可以执行的程序。这个链接的过程就是静态链接。

静态链接的局限性内存占用大、更新困难

 例如,假设我们编写了一个具有某些处理功能的函数MyFunc()。应用A和应用B都会使用这个函数。在各个应用的运行文件中内置函数MyFunc()(此处就是Static Link,静态链接)后同时运行这两个应用,内存中就存在了具有同一函数的两个程序。但这会导致内存的利用效率降低。所以,有两个同样的函数,还是有点浪费(图5-5)。

如果采用动态链接库dll文件的方式 ,可以将函数MyFunc()设置为独立的DLL文件,在运行时可以被多个应用共有,因此内存中存在的函数MyFunc()的程序只有一个,从而提高了内存的利用效率:

 Windows 的操作系统本身也是多个DLL 文件的集合体。有时在安装新应用时,DLL 文件也会被追加。应用则会通过利用这些DLL 文件的功能来运行。像这样,之所以要利用多个DLL 文件,其中一个原因就是可以节约内存。而且DLL 文件还有一个优点就是更新方便,在不变更EXE文件的情况下,只通过升级DLL 文件就可以更新。 

通过调用_stdcall来降低文件程序的大小

  通过调用_stdcall来减小程序文件的方法,是用C 语言编写应用时可以利用的高级技巧。不过,这一思路应该也可以应用在其他编程语言中。这一方法的核心逻辑是针对栈清理处理的所在方(调用方/被调用方)。栈清理是指,把不需要的数据从接受和传递参数时使用的内存上的栈区域中清理掉

  在C语言中,调用函数后,需要执行栈清理处理的指令,该指令不是由程序记述的,而是哎程序编译时由编译器自动附加到程序中的。编译器默认将该处理附加在函数的调用方

下面举例说明栈清理操作默认附加在函数调用方和被调方在内存中的占用情况:

  例如,在代码清单5-1 中,从函数main() 中调用了函数MyFunc()。按照默认设定,栈的清理处理会附加在函数main() 这一方。在同一个程序中,同样的函数可能会被多次反复调用。而如果是同样的函数,栈清理处理的内容也是一样的。由于该处理是在调用函数一方,因此就会导致同一处理被反复进行,造成了内存的浪费

// 代码5-1 C语言的函数调用程序示例
// 函数调用方
void main()
{
    int a;
    a = MyFunc(123, 456);
}
// 被调用方
int MyFunc(int a, int b)
{
    ...
}

  将代码清单5-1 中调用函数MyFunc() 的部分用汇编语言来表示,就如代码清单5-2 所示。最后1行的处理就是清理处理:

// 代码5-2  调用MyFunc() 的部分程序(汇编语言)

push 1C8h                                                   ←将参数 456 (= 1c8h) 存入栈中
push 7Bh                                                     ← 将参数123 (= 7Bh) 存入栈中
call @LTD+15 (MyFunc)(00401014)           ←调用MyFunc() 函数
add esp, 8                                                   ←运行栈清理

 C 语言通过栈来传递函数的参数。push是往栈中存入数据的指令。32 位CPU 中,1 次push 指令可以存储4 个字节的数据。代码5-2中,由于使用了两次push指令把两个参数(456 和123)存入到了栈中,因此总的来说就是存储了8字节的数据。通过call指令调用函数MyFunc() 后,栈中存储的数据就不再需要了。于是这时就通过add esp, 8 这个指令,使存储着栈数据的esp 寄存器B前进8 位(设定为指向高8位字节地址),来进行数据清理(CPU 中,栈中堆积的最高位的数据地址是保存在esp寄存器中的。连续运行两次pop指令,可以消除两个存储在栈中的4字节数据,而同样的功能也可以通过把esp 的数值加8来实现)。

  栈清理处理,比起在函数调用方进行,在反复被调用的函数一方进行时,程序整体要小一些。这时所使用的就是_stdcall。在函数前加上_stdcall,就可以把栈清理处理变为在被调用函数一方进行:

int _stdcall MyFunc(int a, int b)
{
    ...
}

  设置为_stdcall编译后,和代码5-2中add esp, 8 同样的处理就会在函数MyFunc() 一方执行。虽然该处理只能节约3个字节(add esp, 8 是机器语言的3个字节)的程序大小,不过在整个程序中还是有效果的(图5-7)。

磁盘的物理结构 

  磁盘是通过把其物理表面划分成多个空间来使用的。划分的方式有扇区方式可变长方式两种。一般的Windows计算机所使用的硬盘和软盘,采用的都是扇区方式

扇区方式:将磁盘划分为固定长度的空间。

  磁道:扇区方式中,把磁盘表面分成若干个同心圆的空间就是磁道

  扇区:把磁道按照固定大小(能存储的数据长度相同)划分而成的空间就是扇区。 扇区是对磁盘进行物理读写的最小单位。扇区的示意图见图5-8。

可变长方式:把磁盘划分为长度可变的空间。

  扇区是对磁盘进行物理读写的最小单位。Windows 中使用的磁盘,一般1 个扇区是512 字节。不过,Windows 在逻辑方面(软件方面)对磁盘进行读写的单位是扇区的整数倍。根据磁盘容量的不同,1 簇可以是512 字节(1 簇 = 1 扇区)、1KB(1 簇 = 2 扇区)、2KB、4KB、8KB、16KB、32KB(1 簇 = 64 扇区)。磁盘的容量越大,簇的容量也越大。 不管是硬盘还是软盘,不同的文件是不能存储在同一个簇中的,因此不管是多么小的文件,都会占用1 簇的空间。

  以簇为单位进行读写时,1簇中没有填满的区域会保持不被使用的状态。虽然这看起来是有点浪费,不过该机制就是如此规定的,所以我们也没有什么好办法。另外,如果减少簇的容量,磁盘访问次数就会增加,就会导致读写文件的时间变长。由于在磁盘表面上,扇区之间的分界必要的,因此,如果簇的容量过小,磁盘的整体容量也会减少扇区和簇的大小,是由处理速度和存储容量的平衡来决定的。 

结尾

  本文总结了磁盘的相关内容,介绍了内存和磁盘的关系,并通过磁盘缓存和虚拟内存两种机制体现内存和磁盘的密不可分;由于内存的有限,编程时应该尽可能节约内存,本章总结了两种节约内存的编程方法,即使用dll动态链接库代替静态链接和通过_stdcall改变栈清理机制的处理方;最后在物理层面介绍了磁盘的结构,包括扇区和簇的概念。 

  这篇文章就总结到这里吧,下一篇可能重点总结程序从编写到运行的过程相关的内容。除此之外还会进一步更新红队打靶的解析和渗透测试相关的技术分享,恳请希望读者们多多支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1024637.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Java的流浪动物救助及领养管理设计与实现

前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 👇🏻…

机器人制作开源方案 | 随叫随到的智能垃圾桶

作者:卢智浩 尹宗岱 胡文珺 付文智 陈星 单位:江汉大学 指导老师:侍中楼 李巍 本作品围绕探索者场景和应用主题,基于当今时代“智能家”的快速发展,智慧生活成为未来的一大发展趋势,因此我们设计了此款可…

基于Java网络书店商城设计实现(源码+lw+部署文档+讲解等)

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…

从零开始学习 Java:简单易懂的入门指南之Stream流(二十七)

Stream流 Stream流1.体验Stream流2.Stream流的常见生成方式3.Stream流中间操作方法4.Stream流终结操作方法5.Stream流的收集操作6.Stream流综合练习 Stream流 1.体验Stream流 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合,存储多个字符串元素把集合中…

GO-日志分析

GO-日志分析 log包简介 Go提供了logger包来做日志记录。使用方式如下所示 package mainimport ("log""os" )func main() {// 创建一个新的日志文件.默认是stdOutfile, err : os.Create("app.log")if err ! nil {log.Fatal(err)}defer file.Cl…

Linux系统远程访问另一台Windows系统的解决方案

SSH方法 在windows上安装openssh server,在 linux上安装openssh。通常linux会自带openssh,故这里只讲解windows上安装openssh server的方法 1、检查openssh server是否存在 以管理员身份进入Powershell,输入以下命令 Get-WindowsCapabili…

Win10、Win11家庭版开启远程桌面

Win11家庭版开启远程桌面 在windows家庭版中,是不提供远程桌面服务的,你没有办法使用远程桌面连接到windows家庭版中。当然, 你可用升级windows 版本到专业版,这样就可用享受到windows自带的远程桌面服务了。 我的电脑是win11家庭…

【Linux基础】第27讲:Linux查找和过滤命令(二)——grep命令

Grep命令 grep是根据文件的内容进行查找,会对文件的每一行按照给定的模式(patter)进行匹配查找 基本格式: grep [options]范围 [options] 主要参数 -c: 只输出匹配行的计数 -i : 不区分大小写 -n: 显示匹配行及行号 -w: 显示整个…

【鸽鸽送书第一期】 | 实现可观测性平台的技术要点是什么?文末参与送书哦!

🎬 鸽芷咕:个人主页 🔥 个人专栏:《粉丝福利》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活! 文章目录 📋 前言实现可观测性平台的技术要点是什么?1.兼容全域信号量2.所谓全域信号量有哪些&#x…

除了天地图,还有哪些平台可以标绘地图?

想要在地图上标绘业务数据或制作个人地图,却难以找到一款得心应手的地图标绘平台。 在经过一番探索查找之后,发现天地图的标注功能还比较适用。 天地图中的标注 在天地图中,可以将现有的数据导入与地图进行叠加,也可以将绘制的地…

计算机网络工程师多选题系列——计算机网络

2 计算机网络 2.1 网络技术基础 题型1 TCP/IP与ISO模型的问题 TCP/IP由IETF制定,ISO由OSI制定; TCP/IP分为四层,分别是主机-网络层、互联网络层、传输层和应用层;OSI分为七层,分别是物理层、数据链路层、网络层(实…

Visual Studio 更新:远程文件管理器

Visual Studio 中的远程文件管理器可以用来访问远程机器上的文件和文件夹,通过 Visual Studio 自带的连接管理器,可以实现不离开开发环境直接访问远程系统,这确实十分方便。 自从此功能发布以来,VS 开发团队努力工作,…

【2023年11月第四版教材】第13章《资源管理》(合集篇)

第13章《资源管理》(合集篇) 1 章节说明2 管理基础2.1 术语2.2 项目经理的权力有5种来源2.3 优秀团 队的建设5个阶段2.4 激励理论2.4.1 马斯洛需求层次理论2.4.2 赫茨伯格双因素理论:★★★2.4.3 X理论(不好)步丫理论&…

一些真实的app渗透与算法hook

app1 apk文件下载到电脑,adb install 安装到真机上,打开是一个注册页面 真机把SocksDroid打开,随便输个电话号,电脑开charles抓包: 我们放到burp重发器里,改参数重发,不出意外,果然…

低代码开发平台的优点和缺点

随着数字化转型的加速,企业需要更快速地开发和交付应用程序,以适应市场需求和客户需求的变化。在这种情况下,低代码平台成为了企业的首选方案之一。 想象一下,你可以用一个可视化工具构建自己的应用程序,而无需编写繁琐…

面试官:Vue3.0 性能提升主要是通过哪几方面体现的?

🎬 岸边的风:个人主页 🔥 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想,就是为了理想的生活 ! 目录 一、编译阶段 diff算法优化 静态提升 事件监听缓存 SSR优化 二、源码体积 三、响应式系统 一、编译阶段 回顾…

jeecg-boot 基础使用

一 。 页面增加基础使用 先在数据库进行数据定义 然后在页面属性修改显示方式 保存 同步数据库 然后测试 没有问题 选取需要的数据然后生成代码 然后保存 效果 如果需要关联的话 视频 JeecgBoot低代码开发—零基础入门视频_哔哩哔哩_bilibili 文档 如何配置报表菜…

MQ - 07 基础篇_消费者客户端SDK设计(上)

文章目录 导图概述消费模型的选择Pull 模型1. 服务端 hold 住请求2. 服务端有数据的时候通知客户端Push 模型Broker 内置 Push 功能Broker 外独立实现 Push 功能的组件在客户端实现伪 Push 功能Pop 模型分区消费模式的设计独占消费共享消费广播消费灾备消费总结导图

【Linux系统编程】进程概念与基本创建

文章目录 1. 进程的概念2. 进程描述—PCB3. task_struct—PCB的一种4. task_ struct内容分类5. 查看进程 这篇文章我们来学习下一个概念——进程 1. 进程的概念 那什么是进程呢,我们该如何理解它呢? 如果我们打开电脑的任务管理: 我们看到这…

7.zigbee开发,低功耗,通信加密开发

一。低功耗 1.低功耗应用场景 1、不利于更换电池的设备 2、手持便携设备 3、实时性要求不高的设备 2.低功耗工作原理 1、时钟降至最低 2、暂时不用的外设关闭、需要在启动 3、I/O配置 用电情况可以简化为: 等一会运行一下。 3.zigbee实现低功耗 1.协调器路由器终端…