嵌入式知识点总结 操作系统 专题提升(五)-内存

news/2025/2/12 15:36:25/

针对于嵌入式软件杂乱的知识点总结起来,提供给读者学习复习对下述内容的强化。

目录

1.在1G内存的计算机能否malloc(1.2G)?为什么?

2.malloc能申请多大的空间?

3.内存管理有哪几种方式?

4.什么虚拟内存?

5.解释下内存碎片,内碎片,外碎片?

6.解释下虚拟地址,逻辑地址,线性地址,物理地址?

7.虚拟内存置换方法是怎么样的?

8.给你一个类,里面有static,virtual之类的,来说一说这个类的内存分布?

9.假设临界区资源释放,如何保证只让一个线程获得临界区资源而不是都获得?

10.操作系统中的缺页中断是什么?

11.OS缺页置换算法如何实现的?

12.系统调用是什么,你用过哪些系统调用,和库函数有什么区别?

13.为什么要有page cache,操作系统怎么设计的page cache?


1.在1G内存的计算机能否malloc(1.2G)?为什么?

在一台拥有1GB内存的计算机上,调用 malloc(1.2G) 是不可能成功的,因为操作系统会检查可用的内存空间。在这种情况下,系统只能分配最多1GB的内存,超出了这个限制,malloc 会返回 NULL,表示分配失败。

这里的原因有几个方面:

物理内存限制:计算机的物理内存只有1GB,操作系统无法为单一进程分配超过这个值的内存。虽然现代操作系统(如Linux、Windows)支持虚拟内存,但虚拟内存并不是无限的。

操作系统的内存管理:即使系统使用虚拟内存,操作系统通常会设置一定的内存限制来避免进程超出可用内存范围,尤其是对于单个进程的内存分配。所以即使你有足够的交换空间(swap space),系统仍会限制进程分配过多内存。

虚拟内存:如果系统启用了虚拟内存,并且交换空间足够大,操作系统可能会允许你申请超过物理内存的内存量。但是,这会导致频繁的磁盘交换,严重影响性能,且并不意味着所有的内存都会被实际分配给进程。

malloc能够申请的空间大小与物理内存的大小没有直接关系,仅与程序的虚拟地址空间相关。
程序运行时,堆空间只是程序向操作系统申请划出来的一大块虚拟地址空间。应用程序通过malloc申请空间,得到的是在虚拟地址空间中的地址,之后程序运行所提供的物理内存是由操作系统完成的。
本题要申请空间的大小为 1.2G=230x1.2 Byte ,1.2G=(1024*1024*1024)*1.2Byte转换为十六进制约为 4CCCCCCC,这个数值已经超过了 int 类型的表示范围,但还在 unsigned 的表示范围。幸运的是malloc 函数要求的参数为 unsigned 。见下面的示例代码。

#include <stdio.h>
#include <stdlib.h>int main() {char *p;const unsigned k = 1024 * 1024 * 1024 * 1.2; // 计算内存大小,1.2GBprintf("%u\n", k); // 输出计算的内存大小p = (char *)malloc(k); // 申请内存if (p != NULL)printf("ok\n");elseprintf("error\n");free(p); // 释放内存return 0;
}

该程序计算 1.2GB 的内存大小并尝试进行内存分配。

在1GB内存的计算机上,通常因为系统的物理内存限制(除非系统配置了非常大的交换空间),malloc 很可能会失败,返回 NULL,然后打印 error

如果系统有足够的内存(或者有足够的交换空间),程序将成功分配内存,并打印 ok

现代操作系统使用虚拟内存机制,允许程序使用比物理内存更大的地址空间。

虚拟内存通过将部分数据存储在磁盘(如交换分区或页面文件)上来扩展可用内存。

因此,即使物理内存不足,malloc(1.2G) 也可能成功,因为操作系统会将部分数据交换到磁盘。

2.malloc能申请多大的空间?

malloc 可以申请多大的空间,取决于多个因素,包括操作系统的内存管理、硬件架构、操作系统的限制和系统配置。下面是一些影响 malloc 可分配内存大小的关键因素:

32位系统:在32位操作系统中,单个进程的虚拟地址空间通常限制为4GB(理论上是 2^32 字节)。在这种系统上,malloc 申请的最大内存会受到该限制的影响。实际上,由于操作系统和硬件的配置,通常只有2GB或者更少的地址空间可以供进程使用(剩余的内存地址用于操作系统自身),并且受限于内存碎片和内存管理策略。

64位系统:在64位操作系统中,虚拟地址空间大大增加,理论上支持的内存可以高达2^64 字节,极其庞大。实际上,操作系统和硬件会有一些实际限制(如硬件支持的最大内存、操作系统的配置等)。在64位系统中,malloc 能够申请的空间大大增加,可能达到数TB甚至更多。

Linux:Linux 操作系统中的 malloc 申请内存的最大限制通常受到物理内存、交换空间以及进程最大虚拟内存空间的限制。在64位 Linux 系统上,malloc 的最大内存限制可以非常大(通常由操作系统内核和硬件支持来决定),但也取决于系统配置(如 ulimit 设置、内存映射、虚拟内存设置等)。malloc 的实际限制也可能受到内存碎片化和系统资源的影响。

Windows:Windows 操作系统也支持大内存分配,但其最大分配空间受到物理内存、虚拟内存(例如页面文件的大小)以及系统架构的影响。在32位 Windows 上,单个进程的最大地址空间限制通常为2GB(对于某些配置为3GB),而在64位 Windows 上,理论上支持极大的虚拟内存空间,但仍受硬件和操作系统配置限制。

3.内存管理有哪几种方式?

1. 连续内存分配(Contiguous Allocation)

概念:所有的进程都在物理内存中占据一个连续的内存区域。

特点:简单高效,但容易造成内存碎片。

类型

单一连续分配:一个进程只占用一个连续的内存区域,适用于短小的程序。

固定分区分配:内存被分为若干个固定大小的区块,进程被分配到适合大小的区块中。

动态分区分配:内存区块大小根据需要动态分配,不固定,但会随着时间推移出现碎片。

优缺点

优点:容易实现,访问效率高。

缺点:随着时间的推移,内存碎片问题严重,可能导致无法找到足够的连续内存。

2. 非连续内存分配(Non-contiguous Allocation)

概念:进程在内存中的分配不要求是连续的,而是通过地址映射和分页技术来管理。

实现方式

分页(Paging):将内存和进程的地址空间都分为固定大小的块(页),进程的每个页可以在物理内存中的任何位置,不需要连续。

分段(Segmentation):将进程划分为多个逻辑段(如代码段、数据段、堆栈段等),每个段在内存中可以独立分配,段的大小不固定。

优缺点

优点:消除内存碎片问题,灵活性更高。

缺点:需要复杂的内存映射和地址转换,可能引入管理开销。

3. 虚拟内存管理(Virtual Memory Management)

概念:虚拟内存通过将硬盘的一部分作为扩展内存(交换空间或页面文件),允许程序使用比物理内存更多的内存。

实现方式

页面交换(Paging):将内存分为固定大小的页面,操作系统根据需要将内存页交换到硬盘中,进程运行时只需加载当前需要的页面。

分段交换:将整个段(如代码段)交换到硬盘中,适合较大块的内存管理。

优缺点

优点:程序能够使用比物理内存更多的内存,支持多任务操作。

缺点:访问硬盘时速度较慢,可能引发“交换抖动”(Thrashing),即频繁从硬盘交换数据,导致性能下降。

4. 内存池管理(Memory Pooling)

概念:内存池将内存预先分配好并组织为一个内存池,进程或线程从池中申请内存。这种方式常用于需要频繁分配和释放内存的场景。

特点:避免频繁的内存分配和释放,提升效率。

优缺点

优点:提高内存分配效率,避免碎片化。

缺点:可能造成内存的浪费,尤其是当内存池的大小过大或过小时。

5. 伙伴系统(Buddy System)

概念:内存被划分为大小为2的幂次方的块,每个块有一个伙伴,合并和分裂操作通过伙伴来管理,保证内存分配和回收时没有碎片。

特点:内存分配时每次分配2的幂次方大小的内存块,减少内存碎片。

实现:当一个内存块释放时,操作系统会查找其“伙伴”是否空闲,若空闲,则合并成一个更大的内存块。

4.什么虚拟内存?

虚拟内存是一种让程序认为它拥有连续的大内存的技术,实际上程序使用的内存可能分布在不同的物理位置,甚至不完全在内存中。

简单来说,虚拟内存让程序可以使用比实际物理内存更多的内存。操作系统通过将不常用的数据暂时存储到硬盘上的交换空间(swap space)来实现,只有当需要时再将它们加载回内存。

  • 让程序可以使用更多内存,比实际物理内存大。
  • 增强多任务处理能力,让多个程序能并行运行。

5.解释下内存碎片,内碎片,外碎片?

内碎片是分配的内存比需要的内存多,造成空间浪费。

外碎片是内存中有很多小块空闲空间,但这些小块不连续,无法被大内存块使用。

6.解释下虚拟地址,逻辑地址,线性地址,物理地址?

虚拟地址:程序看到的地址,由操作系统管理,跟物理内存无关。

逻辑地址:程序生成的地址(有时和虚拟地址一样),在分段管理中使用。

线性地址:在分页系统中,经过段映射后的地址,还需要分页才能得到物理地址。

物理地址:实际的内存地址,硬件操作的地址,直接对应内存中的位置。

7.虚拟内存置换方法是怎么样的?

虚拟内存的置换方法主要是通过选择合适的页面来腾出内存空间,常见的置换算法有:

FIFO:先来先服务,简单,但可能不够高效。

LRU:选取最久未使用的页面,效果较好。

LFU:选取最少使用的页面,适合访问频率较低的场景。

OPT:理论上最佳,但不可实现。

Random:随机置换,简单但不高效。

实际操作系统会根据不同情况选择适合的置换算法,以平衡性能和效率。

8.给你一个类,里面有static,virtual之类的,来说一说这个类的内存分布?

实例数据:存储在堆或栈中,每个对象有一份副本。

静态成员:类的所有实例共享,存储在数据段中。

虚函数表(Vtable):存储在只读数据区,类中每个对象有一个指向虚函数表的指针(Vptr)。

9.假设临界区资源释放,如何保证只让一个线程获得临界区资源而不是都获得?

要保证 临界区 资源的 互斥访问,通常需要使用同步机制,确保在同一时间只有一个线程能访问临界区。最常见的方法是使用 互斥锁(mutex)信号量(semaphore)

互斥锁(Mutex):在进入临界区时,线程会先尝试获取锁,如果锁已经被其他线程占用,当前线程将被阻塞,直到锁被释放。这样,多个线程就不会同时进入临界区。

信号量(Semaphore):信号量控制临界区的资源数量,确保不超过一定数量的线程同时进入临界区。二值信号量通常用于实现互斥锁。

10.操作系统中的缺页中断是什么?

缺页中断是虚拟内存管理中的一个重要概念。当程序访问一个当前不在物理内存中的页面时,会触发缺页中断。操作系统通过捕获这个中断并进行处理,加载所需的页面到内存中,从而让程序继续执行。

触发条件:程序访问的虚拟地址在物理内存中没有对应的页面。

处理过程

  1. 触发缺页中断。
  2. 操作系统暂停程序,查看页面是否在磁盘中的交换空间(Swap Space)或其他地方。
  3. 如果页面在硬盘中,将其加载到内存中。
  4. 更新页表,将虚拟地址映射到新的物理地址。
  5. 继续执行程序。

11.OS缺页置换算法如何实现的?

缺页置换算法是在缺页中断发生时,操作系统决定哪些页面需要被换出,并选择一个合适的页面进行替换。常见的缺页置换算法有:

LRU(Least Recently Used):选择最久未使用的页面进行置换。操作系统可以通过维护一个队列或时间戳来跟踪页面的使用情况,选择最近最少使用的页面换出。

FIFO(First In, First Out):最早加载到内存的页面优先被置换。操作系统维护一个队列,新的页面在队列尾部,最老的页面在队列头部,队列头部的页面会被置换。

OPT(Optimal):理论上最优的算法,选择未来最长时间不会被使用的页面进行置换。缺点是不可实现,因为操作系统无法预测未来的访问模式。

随机置换:操作系统随机选择一个页面进行置换,简单但不一定高效。

12.系统调用是什么,你用过哪些系统调用,和库函数有什么区别?

系统调用(System Call):系统调用是应用程序与操作系统内核之间的接口。当应用程序需要操作系统提供的服务(如文件操作、进程管理、内存分配等)时,会通过系统调用与操作系统交互。常见的系统调用包括 read(), write(), fork(), exec() 等。

库函数(Library Function):库函数是由程序库提供的预定义函数,它们封装了常见的操作(如数学计算、字符串处理等)。库函数通常是用户空间的代码,直接调用库函数不会进入操作系统内核。

13.为什么要有page cache,操作系统怎么设计的page cache?

Page Cache 是操作系统用来提高磁盘I/O性能的一种机制。它将磁盘文件内容缓存到内存中,避免每次访问文件时都需要从磁盘读取,提高了文件访问的速度。

原因

磁盘访问速度远远低于内存,频繁的磁盘I/O会极大影响性能。

文件内容往往会被多次访问,缓存可以减少重复读取磁盘的开销。

设计

操作系统会在内存中为文件数据保留一个缓存区,这个区域叫做页面缓存(Page Cache)。

当程序访问文件时,操作系统首先检查是否文件的数据已存在于缓存中。如果存在,直接从内存返回数据;如果不存在,操作系统会从磁盘读取数据并缓存到内存中。

采用 LRU 或其他替换算法来管理缓存中的数据,保证高效地使用有限的内存空间。


http://www.ppmy.cn/news/1571455.html

相关文章

除了Redux-Thunk,还有哪些常用的中间件?

除了 Redux-Thunk,以下是一些常用的 Redux 中间件: 1. Redux-Saga 功能:用于处理复杂的异步操作和副作用。使用生成器函数,使得异步代码更易于管理和测试。安装:npm install redux-saga2. Redux-Logger 功能:用于记录每个 dispatched action 和状态变化,便于调试。安装…

利用爬虫获取1688商品详情的实战案例指南

在电商领域&#xff0c;快速获取商品数据对于市场分析、竞争情报收集以及产品选品至关重要。1688作为国内领先的B2B电商平台&#xff0c;拥有海量的商品资源。通过爬虫技术&#xff0c;我们可以高效地获取这些商品的详细信息&#xff0c;为商业决策提供有力支持。 一、1688商品…

链式前向星_记录

链式前向星总结 测试时尽量使用静态数组 测试时尽量使用静态数组 value和next数组是可以被cnt瞬间归零的&#xff0c;所以只要静态给狗他俩的空间即可&#xff0c;使用cnt0相当于立刻清空所有内容。 head也应该设置为静态&#xff0c;因为无论如何head的值都要全改为-1&#x…

日志2025.2.9

日志2025.2.9 1.增加了敌人挥砍类型 2.增加了敌人的死亡状态 在敌人身上添加Ragdoll&#xff0c;死后激活布偶模式 public class EnemyRagdoll : MonoBehaviour { private Rigidbody[] rigidbodies; private Collider[] colliders; private void Awake() { rigidbodi…

【物联网】电子电路基础知识

文章目录 一、基本元器件1. 电阻2. 电容3. 电感4. 二极管(1)符号(2)特性(3)实例分析5. 三极管(1)符号(2)开关特性(3)实例6. MOS管(产效应管)(1)符号(2)MOS管极性判定(3)MOS管作为开关(4)MOS管vs三极管7. 门电路(1)与门(2)或门(3)非门二、常用元器件…

在服务器部署JVM后,如何评估JVM的工作能力,比如吞吐量

在服务器部署JVM后&#xff0c;评估其工作能力&#xff08;如吞吐量&#xff09;可以通过以下步骤进行&#xff1a; 1. 选择合适的基准测试工具 JMH (Java Microbenchmark Harness)&#xff1a;适合微基准测试&#xff0c;测量特定代码片段的性能。Apache JMeter&#xff1a;…

TCP传输层协议

TCP 全称为 "传输控制协议(Transmission Control Protocol"). 人如其名, 要对数据的传 输进行一个详细的控制。 对于TCP的学习主要就是要知道TCP协议报头之中各个字段的作用 除了数据之外总共报头加起来是20个字节 16位源端口号与目的端口号 这是最容易理解的两…

微信小程序的behaviors和vuex功能对比

声明&#xff1a;以下内容为AI 产出总结&#xff0c;内容比较有价值&#xff0c;仅供学习 behaviors 和 Vuex 的功能并不相似&#xff0c;它们的用途和设计目标完全不同。以下是它们的对比&#xff1a; --- ### 1. **behaviors 的功能** - **定位**&#xff1a;behaviors 是…