- 单片机是没有操作系统的,每次写完代码都是通过一些工具将程序直接烧录进去,这样程序才能跑起来。单片机的CPU是直接操作内存的物理地址。在这种情况下,要想在内存中同时运行两个程序是不可能的,程序会崩溃。那么操作系统为了解决这个问题,就引入了虚拟内存的概念。可以将进程所使用的地址隔离开来,操作系统为每个进程分配独立的一套虚拟地址。
- 进程持有的虚拟地址会通过CPU芯片中的内存管理单元MMU的映射关系来转换变成物理地址,然后通过物理地址访问内存。
- 操作系统主要通过内存分段和内存分页来管理虚拟地址和物理地址的关系
内存
理解的内存
内存是用于存放数据的硬件。程序执行之前需要先放到内存中才能被CPU处理。
操作系统对于内存的管理
- 负责空间分配和回收
- 需要提供某种技术从逻辑上对内存空间进行扩充
- 提供地址转换功能,负责程序的逻辑地址与物理地址的转换
- 提供内存保护功能,保证各个进程在各自存储空间运行,互不干扰。
常见的内存分配方式
静态存储区域分配
内存在程序编译的时候就已经分配好,这块内存在程序整个运行期间都存在。例如全局变量,static变量。
在栈上创建
执行函数的时候,函数内局部变量的存储单元都可以在栈上创建,函数执行结束的时候被释放。栈分配运算内置于处理器的指令集中,效率很高,分配的内存容量有限。
堆上分配
malloc和new
常见的内存分配内存错误
分配未成功却使用了它
检查是否为NULL
分配成功但是尚未初始化就使用
需要赋初值
操作越过内存界限
数组操作越界
忘记释放内存
会出现内存耗尽的情况
释放内存却继续使用它
- 不清楚是否已经释放内存
- 返回了栈内存的指针或者引用
- 产生野指针,也就是在使用free或者delete释放内存之后,没有将指针设置为NULL
内存交换
内存空间紧张的时候,系统将内存中的某些进程暂时换出内存,把外存中某些已具备运行条件的进程换入内存。
内存交换换出的进程保存在哪里
保存在磁盘中。具有兑换功能的操作系统中,通常把磁盘空间分为文件区和对换区:文件区存放文件,主要追求存储空间利用率,因此采用离散分配方式;对换区空间只占磁盘空间的小部分,被换出的进程数据放在对换区,主要追求换入换出速度,所以采用连续分配方式,I/O速度比文件区快。
哪些进程被优先考虑
优先换出阻塞进程,优先级低的进程并且考虑进程在内存的驻留时间。
PCB常驻内存,不会被换出。
什么时候进行内存交换
许多进程运行且内存吃紧时进行内存交换,系统负荷降低就暂停。
内存交换和覆盖有什么区别
内存覆盖
可以把用户空间分成一个固定去和若干个覆盖区。将经常活跃的部分放在固定区,其余部分按照调用关系分段,首先将那些即将访问的段放入覆盖区,其他段放在外存中,在需要调用之前,系统将其调入覆盖区,替换覆盖区中原有的段。
注意:内存中能够更新的地方只有覆盖区的段,不在覆盖区的段会常驻内存。
区别
交换主要是在不同进程或者作业之间进行,而覆盖是用于同一程序或者进程中。
抖动
刚换出的页面马上又要换入内存,刚换入的页面马上又要换出外存,这种频繁的页面调度成为抖动或者颠簸。产生抖动的主要原因是进程频繁访问的页面数目高于可用的物理块数(分配给进程的物理块不够)。
为了研究应该为每个进程分配多少个物理块,提出了就”进程工作集“的概念。
内存交换需要注意哪些
- 交换需要备份存储,通常是快速磁盘,必须足够大,并且提供对这些内存映像的直接访问。
- 为了有效使用CPU,需要每个进程的执行时间比交换时间长
- 交换空间通常作为磁盘的一整块
- 交换通常在有许多进程运行且内存吃紧的时候开始启动
动态分区算法
虚拟技术
虚拟技术就是把一个物理实体转换成多个逻辑实体
主要有两种虚拟技术:时间复用和空间复用。
- 多进程和多线程:多个进程能在同一个处理器上并发执行使用了时分复用技术,让每个进程轮流占用处理器,每次只执行一个小时间片并快速切换。
- 虚拟内存使用了空分复用技术:将物理内存抽象为地址空间,每个进程都有各自的地址空间。地址空间的页被映射到物理内存,地址空间的页不需要全部在物理内存中,当使用到一个没有在物理内存的页时,执行页面置换算法,将该页置换到内存中。
虚拟内存
虚拟内存目的
为了让物理内存扩充成更大的逻辑内存,从而让程序获得更多的可用内存。
操作系统将内存抽象成地址空间,每个程序拥有自己的地址空间,这个地址空间被分割成多个块,每一块称为一个页。这些页被映射到物理内存,但是不需要映射到连续的物理内存,也不需要所有页都必须在物理内存中
程序从堆中动态分配内存的时候,虚拟内存上如何操作
页表:是一个存放在物理内存中的数据结构,记录了虚拟页与物理页的映射关系。
进行动态内存分配的时候,操作系统会在硬盘中创建或者申请一段虚拟内存空间,并更新到页表(分配一个页表条目PTE,使该PTE指向硬盘上这个新创建的虚拟页),通过PTE建立虚拟页和物理页的关系。
逻辑地址转换为物理地址
通常,在系统中设置一个页表寄存器PTR,存放页表在内存中的起始地址和页表长度。进程未执行的时候,页表的起始地址和页表的长度放在进程控制块中,进程被调度的时候,操作系统内核会把他们放到页表寄存器中。
- 根据逻辑地址计算出页号、页内偏移量
- 判断页号是否越界
- 查询页表,找到页号对应的页表项,确定页面(内存块号)
- 用内存块号×页面大小和页内偏移量相加而得到物理地址
- 访问目标内存单元
而非你也存储管理中,只要确定每个页面大小,就可以确定逻辑地址结构。
快表
快表是一种高速缓冲存储器,又称为联想寄存器TLB,用来存放页表项。在没有快表的情况下,一个虚拟地址要转成一个物理地址至少需要两次访问物理内存,第一次是查询内存中的页表,第二次是访问物理页框。如果有暂存着目标页表项的快表,则通过快表访问页表会比在内存中访问页表快很多,有利于缩短从一个虚拟地址转换成一个物理地址的过程的时间。
交换空间与虚拟内存的关系
交换空间
Linux中的交换空间在物理内存RAM被充满时使用。如果系统需要更多的内存资源而物理内存已满,内存中不活跃的页就会被移到交换空间去。交换空间位于硬盘驱动器上,它比进入物理内存慢。交换空间可以是一个专用的交换分区、交换文件或者两者组合。
交换空间总大小应该相当于你计算机内存的两倍和32MB这两个值中较大的一个,但是不能超过2GB.
虚拟内存
是文件数据交叉连接的活动文件。是Windows目录下的一个“WIN386.SWP"文件,这个文件会不断扩大和自动缩小。而且虚拟内存使用的是硬盘的空间,因为硬盘空间大。
内存碎片
内部碎片
内部碎片是已经被分配出去而不能利用的空间。
外部碎片
外部碎片是没有被分配出去,但是由于太小了无法分配给新进程的内存空闲区域。
如何消除碎片文件
外部碎片
- 紧凑技术,这需要动态重定位寄存器的支持。
- 内存交换
回收内存的时候要尽可能将相邻的空间合并。
内部碎片
优化应用程序中的内存管理方式,不要频繁申请、释放内存空间,减少外部碎片。