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

目录

写在开头

内存与磁盘的关系

基本关系

磁盘缓存

虚拟内存 

节约内存的编程方法

通过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.mzph.cn/news/83042.shtml

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

相关文章

操作系统(5-7分)

内容概述 进程管理 进程的状态 前驱图 同步和互斥 PV操作(难点) PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下: P(S)&#…

【计算机网络】——传输层

//图片取自王道,仅做交流学习 一、传输层提供的服务 物理层、数据链路层、网络层是通信子网。 传输层:它属于面向通信部分的最高层,同时也是用户功能的最低层 为应用层提供通信服务使用网络层的服务 网络层提供主机之间的逻辑通信。 1、传输…

SpringMVC之JSR303与拦截器

目录 一.JSR303 1.什么是JSR303 2.为什么使用JSR303 3.JSR303常用注解 4.快速入门 4.1导入Maven依赖 4.2 配置校验规则 4.3 对服务端数据添加进行校验 4.4 结果测试 二.拦截器 1.什么是拦截器 2.拦截器与过滤器 3.应用场景 4.基本拦截器配置 5 案例演示&#xff0…

区块链实验室(23) - FISCO中PBFT耗时与流量特征

前面的实验(区块链实验室(11) - PBFT耗时与流量特征)用仿真的PBFT观察耗时。现在用真实的Fisco网络再次观察其特征。同样地,用相同的网络,即100个节点构成的无标度网络。在每个节点上发起10次交易,记录每次交易的耗时。结果见下图所示。 前半…

VSCode『SSH』连接服务器『GUI界面』传输

前言 最近需要使用实验室的服务器训练带有 GUI 画面的 AI 算法模型(pygame),但是我是使用 SSH 连接的,不能很好的显示模型训练的效果画面,所以下面将会讲解如何实现 SSH 连接传输 Linux GUI 画面的 注:我们…

Postman —— HTTP请求基础组成部分

一般来说,所有的HTTP Request都有最基础的4个部分组成:URL、 Method、 Headers和body。 (1)Method 要选择Request的Method是很简单的,Postman支持所有的请求方式。 (2)URL 要组装一条Request…

华为HCIA(五)

Vlan id 在802.1Q中 高级ACL不能匹配用户名和源MAC 2.4G频段被分为14个交叠的,错列的20MHz信道,信道编码从1到14,邻近的信道之间存在一定的重叠范围 STA通过Probe获取SSID信息 Snmp报文 网络管理设备异常发生时会发送trap报文 D类地址是…

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

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

亚马逊云科技 Amazon Lightsail :一种在云服务器上运行容器的简单方法

当向开发人员介绍亚马逊云科技云服务时,通常会花一点时间来介绍并演示 Amazon Lightsail 。它是迄今为止开始使用亚马逊云科技的最简单方法。使用它,您在几分钟内即可在自己的虚拟服务器上运行您的应用程序。而后增加了在 Amazon Lightsail 上部署基于容…

C语言字符函数和字符串函数(1)

大家好,我们又见面了,让大家久等了,我们今天就来学习字符函数和字符串函数。 在开启今天的学习之前呢,我来解决一下一些小伙伴平时找不到库函数使用的烦恼,因为我们cplusplus.com最新版本不能够查询函数,我…

排查disabled问题之谷歌新版本特性

问题复现 最近我突然接手一个后台的bug,这个后台很久没有迭代更新了,我也不熟悉业务,所以只能看一下源码,问题很快就复现,测试的修复操作也很正确,就是因为渲染的input标签中存在disableddisabled’属性导…

英国留学生务必谨慎使用ChatGPT!!!

ChatGPT(全名:Chat Generative Pre-trained Transformer),是OpenAI研发的聊天机器人程序,于2022年11月30日发布。ChatGPT是人工智能技术驱动的自然语言处理工具,它能够基于在预训练阶段所见的模式和统计规律…

1.IAR-8051安装

新版安装教程:IAR EW for 8051 简介与安装 新版软件zhuce:IAR EW for 8051 软件注册 - 知乎 这个新版的我也放到网盘里面了,自己自行选择安装 一、下载IAR-8051 链接:https://pan.baidu.com/s/1mYwSQvSjAiSzltrEbK3yAw?pwd43cd …

【产品经理】深入B端SaaS产品设计核心理念

这几年各企业的B端业务都在做SaaS平台,但对SaaS的了解还不是完全全面,对于一些产品的定位以及设计还在探索中 本文讨论“为什么采用SaaS模式”、“SaaS产品有哪些”以及“如何做好SaaS产品设计”三个话题,核心是产品设计,主要从需…

LabVIEW开发航天器模拟器的姿态控制和反作用轮动量管理

LabVIEW开发航天器模拟器的姿态控制和反作用轮动量管理 在过去十年中,航天器一直是现代技术进步的先决条件。迄今为止,为了更好地完成各种实际任务,已经在航天器姿态控制领域进行了大量研究。航天器一旦进入太空,就容易出现不确定…

CSS

CSS CSS是什么 层叠样式表 (Cascading Style Sheets).CSS 能够对网页中元素位置的排版进行像素级精确控制, 实现美化页面的效果. 能够做到页面的样式和结构分离.说白了就是让网页变得好看 什么是样式呢? 大小,位置,间距,颜色&a…

银行发展绿色金融,8条建议为您指路

在《财富潮涌:银行发展绿色经济创新路径》内容中,我们带大家了解了商业银行有关绿色财富、绿色服务及绿色运营的内容。今天,我们将阐述商业银行发展绿色金融的必要性以及在实践中商业银行应该如何发展色金融。 发展绿色金融的必要性与难点 1.…

华为杯数学建模比赛经验分享

再过一周左右,第二十届华为杯数学建模比赛就要开赛了,所以今天分享一下个人数学建模比赛的经验。 今天给大家分享一期关于华为杯数学建模比赛的经验分享,我将从以下三个方面展开说明: (1)如何准备数学建模比赛&#x…

Interceptor的使用场景:拦截请求中的租户信息,注入到租户上下文中

业务场景 在SaaS环境中,租户是最重要的隔离业务数据的属性了,在自己的项目体系环境中,租户id能保证有值。但有个特殊场景,某些特殊权限的账号需要修改指定租户的内容,也即前端会携带租户信息过来,并且内部涉…

共享单车场景下Cat.1网络表现如何?测试结果来了

为帮助行业客户提高Cat.1产品稳定性,近期,天翼物联组织终端客户郑州威科姆科技股份有限公司开展基于中国电信 Cat.1网络下的共享单车体验测试,内容涵盖单车实时位置监控、单车在线率、业务数据延迟、语音播报功能等。测试结果表明&#xff0c…