C/C++中的虚拟内存
文章目录
- 一、虚拟内存
- 二、C中的虚拟内存分配模型
- 三、C++中的虚拟内存分配模型
- 四、堆区和栈区的区别
一、虚拟内存
虚拟内存是一种实现在计算机软硬件之间的内存管理技术,它将程序使用到的内存地址(虚拟地址)映射到计算机内存中的物理地址,虚拟内存使得应用程序从繁琐的内存空间管理中解放出来,通过内存隔离提高了内存安全性。
虚拟内存地址通常是连续的地址空间,由操作系统的内存管理模块控制,在触发缺页中断时利用分页技术将实际的物理内存分配给虚拟内存。同时虚拟内存的空间大小远超出实际物理内存的大小,虚拟内存技术使得进程可以使用比物理内存大得多的内存空间。
二、C中的虚拟内存分配模型

C语言中一个进程的内存映像从低地址开始分为正文段、初始化数据段、未初始化数据段、堆区、栈区五大部分:
- Text段:Text段是指用来存放程序执行代码的一块内存区域,是二进制文件(或者说处理器的机器指令)在内存中的映像。当然也有可能包含一些只读的常数变量,例如字符串常量等。这部分区域的大小在程序运行前就已经确定,并且通常只允许进行读操作,向Text段写会导致Segmention Fault。
- Data段:Data段是指存放程序中已经初始化的全局变量和静态变量的一块内存区域。Data段并不是匿名的,而是映射了程序二进制文件中在编译时就已初始化的数据,由程序初始化。
- BSS段:BSS段存放了未初始化的全局变量和静态变量,由操作系统初始化(清零),且是匿名的不映射任何文件,不占用外存空间,只在运行时占用内存。注意,这里的未初始化指的是没有显示初始化,因为全局变量和静态变量会自动隐式初始化为0,但我们没有必要把这些0都存储起来,从而节省外存空间,这也是BSS段的主要作用。
- 堆区:堆提供了程序运行时的内存分配,堆内存的生命周期在函数之外,大部分语言都提供了堆内存管理函数, 如C语言的
malloc()与free(),因此堆区由用户管理,可控性强。如果当前堆的内存足够程序使用,则不需要与内核交互,在当前堆中寻找可用内存就行,否则的话需要调用brk()系统调用向内核申请空间,堆内存分配的算法非常复杂,既要保证内存分配的实时和快速,又要尽量避免堆中出现过多碎片,由此也就引申出了操作系统中的一系列内存分配算法与分配策略,如FF、BF、WF、NF等。 - 栈区:栈保存了局部变量、函数形参、返回值等,调用一个新的函数会在栈上创建一个新的栈帧,当函数返回时这个栈帧会被自动销毁。一个栈帧包括:函数的返回地址和参数、临时变量(包括函数的非静态局部变量以及编译器自动生成的其他临时变量)、栈帧状态值(EBP和ESP,划定了这个函数的栈帧的范围)。栈的空间分配与堆略有不同,当栈空间用尽后继续push会触发栈空间的扩展,导致Page Fault,然后在内核中调用
expand_stack(),该函数调用acct_stack_growth()来判断是否可以增长栈空间,如果当前栈空间的大小小于RLIMIT_STACK,则可以继续增长栈空间,该过程由内核完成进程不会感知到。当用户的栈空间已经达到允许的最大值时,内核会给进程发送一个Segmentation Fault信号终止该进程,因此进程的栈空间只会增大不会缩小。
三、C++中的虚拟内存分配模型
C++中的虚拟内存分配与C中大体上相似,只在细节处略有不同:
- 常量区:常量区是一块比较特殊的存储区,专门用来存储那些由const修饰的变量以及常量字符串等不能被修改的常量,在程序结束后由系统释放。
- 全局/静态存储区:存放全局变量和静态变量,程序一经编译该区域就会存在。在C++中,由于编译器会对全局变量和静态变量进行自动初始化并赋值,所以并没有像C中一样对初始化变量和未初始化变量进行区分。全局/静态存储区会在程序结束后由系统释放。
- 自由存储区:自由存储区是通过malloc/calloc/realloc分配的内存,并需要通过free释放。如果程序员没有进行free操作,则会造成内存泄露,并在程序结束时由OS进行内存回收。
- 堆区:与C中不同的是,C++中堆是由new申请的内存,并由delete或delete[]释放。
- 栈区:保存函数中的局部变量、函数参数以及返回值。由编译器负责分配释放,函数结束栈变量也随之失效。
四、堆区和栈区的区别
| 堆区 | 栈区 | |
|---|---|---|
| 管理者 | 由用户管理,可控性强 | 由系统管理,分配效率高 |
| 地址扩展 | 从低地址向高地址扩展 | 从高地址向低地址扩展 |
| 申请后的系统响应 | 如果当前堆的内存足够程序使用,则不需要与内核交互,继续在当前堆中寻找可用内存就行。否则的话需要调用brk()系统调用向内核申请空间 | 当栈空间用尽后继续请求会触发栈空间的扩展,导致缺页,然后在内核中调用expand_stack(),该函数调用acct_stack_growth()来判断是否可以增长栈空间,如果当前栈空间的大小小于RLIMIT_STACK,则可以继续增长栈空间。当用户的栈空间已经达到允许的最大值时,内核会给进程发送一个段错误信号终止该进程。 |
| 存储内容 | 由用户决定运行时的内存分配 | 栈保存了局部变量、函数形参、返回值等 |
| 生命周期 | 堆内存的生命周期在函数之外,由用户控制 | 调用一个新的函数会在栈上创建一个新的栈帧,当函数返回时这个栈帧会被自动销毁 |
相关文章:
C/C++中的虚拟内存
文章目录一、虚拟内存二、C中的虚拟内存分配模型三、C中的虚拟内存分配模型四、堆区和栈区的区别一、虚拟内存 虚拟内存是一种实现在计算机软硬件之间的内存管理技术,它将程序使用到的内存地址(虚拟地址)映射到计算机内存中的物理地址&#…...
Qt C++与Python混合编程:补充错误
在提示中,需要引用Python.h,出现错误。 1、找不到Python.h 如果是pro工程,需要在里面配置; INCLUDEPATH /Users/xinnianwang/opt/anaconda3/include LIBS /Users/xinnianwang/opt/anaconda3/lib 如果是CMakeLists.txt需要配…...
2023-04-01:当Go语言遇见FFmpeg视频解码器,使用Go语言改写decode_video.c文件,提升视频解码效率与开发体验。
2023-04-01:当Go语言遇见FFmpeg视频解码器,使用Go语言改写decode_video.c文件,提升视频解码效率与开发体验。 答案2023-04-01: 步骤如下: 1.导入必要的依赖库,包括 fmt、os、unsafe 和其它 FFmpeg 库相关…...
Solidity 学习笔记
主要参考网上资料学习,个人学习笔记有删改,参考出处在文末列出。 0 基础 IDE: remixType Bool: bool public _bool true; 默认false;整型:int、uint、uint256,默认0;地址类型:address,分为 payable 和普…...
ThreadLocal原理
关键点总结: ThreadLocal更像是对其他类型变量的一层包装,通过ThreadLocal的包装使得该变量可以在线程之间隔离和当前线程全局共享。在Thread中有一个threadLocals变量,类型为ThreadLocal.ThreadLocalMap,ThreadLocalMap中key是Th…...
串操作指令详解 MOVS,LODS,STOS,CMPS,SCAS,REP
指令包括:MOVS,LODS,STOS,CMPS,SCAS,REP 串的概念:串是连续存放再内存中的字节块或字块。每个串有一个起始地址和长度, 待操作的数据串称为源串,目的地址称为目标串 目录…...
Java实现判断素数
1 问题 判断101-200之间有多少个素数,并输出所有素数。 2 方法 package homework04; public class Test05 { public static void main(String[] args) { for (int i 101; i < 201; i) { boolean flag true; for (int j 2; j…...
PHP初级教程------------------(2)
目录 运算符 赋值运算符 算术运算符 比较运算符 逻辑运算符 连接运算符 错误抑制符 三目运算符 自操作运算符 编辑 计算机码 位运算符 运算符优先级 流程控制 控制分类 顺序结构 分支结构 If分支 Switch分支 循环结构 For循环 while循环 do-while循环 循环控制 …...
【SQL开发实战技巧】系列(三十五):数仓报表场景☞根据条件返回不同列的数据以及Left /Full Join注意事项
系列文章目录 【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事 【SQL开发实战技巧】系列(二):简单单表查询 【SQL开发实战技巧】系列(三):SQL排序的那些事 【SQL开发实战技巧…...
springBoot自动配置过程介绍
什么是自动配置 以前整合spring mybatis框架时候,需要加很多的bean, 比如说sqlSessionFactory等等 现在springboot帮我们干了,我们只需要引入对应的starter就可以了。 springBoot可以帮我们配置好了一些bean. 如mysql, mogondb相关操作等等ÿ…...
PostgreSQL最后的救命稻草 — pg_resetwal
pg_resetwal— 重置 PostgreSQL 数据库集群的预写日志和其他控制信息 适用版本:PostgreSQL 12/13/14/15语法 pg_resetwal [ -f | --force ] [ -n | --dry-run ] [option...] [ -D | --pgdata ]datadir描述pg_resetwal清除预写日志 WAL,并可选地重置pg_c…...
彻底关闭Windows更新
一、关闭Windows Update服务 1、按“Windows R”键,打开运行对话框,并输入“services.msc”,然后再单击“确定”。 2、在弹出的服务窗口中,找到“Windows Update”选项并双击打开它。 3、在弹出的“Windows Update的属性”对话框…...
Java正则表达式语法
Java正则表达式的语法与示例 | |目录 1匹配验证-验证Email是否正确 2在字符串中查询字符或者字符串 3常用正则表达式 4正则表达式语法 1匹配验证-验证Email是否正确 public static void main(String[] args) { // 要验证的字符串 String str "servicexsoftlab.net&q…...
【2023-3-29】JavaScript使用promise顺序调用函数并抛出异常
JavaScript使用promise顺序调用函数并抛出异常 场景 新建或者编辑时,一个页面中存在多个表单,每个表单都有单独进行表单验证。点击提交时,若有一个表单校验失败,则不能提交。 ps:为啥不放在一个表单中? (…...
Python实现GWO智能灰狼优化算法优化随机森林分类模型(RandomForestClassifier算法)项目实战
说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 灰狼优化算法(GWO),由澳大利亚格里菲斯大学学者 Mirjalili 等人于2014年提出来的一种群智能…...
从redis到epoll到mmap
redis为什么这么快? 比较容易答出的答案 1)纯粹的内存操作 2)单线程操作,不用考虑线程切换 其他优势 3)I/O 多路复用,使用epoll 4)Reactor 设计模式 I/O 多路复用有三种 select、poll、epoll select:使用数组存储轮询 poll:使用链表轮询 epo…...
STM32CubeMX快速构造工程模板(一)
STM32CubeMX作为一个免费开源的软件,能够可视化配置STM32或其他产品硬件资源,能过快速地构造工程模板,很是方便!!! 目录 STM32CubeMX快速构造工程模板 首先第一步,打开软件-点击按钮-输入型号-双击打开。...
Java Web中的ServletContext对象
目录 ServletContext对象 获取上下文初始化参数的相关方法 创建ServletContext对象 1)通过 GenericServlet 提供的 getServletContext() 方法 2)通过 ServletConfig 提供的 getServletContext() 方法 3)通过 HttpSession 提供的 getServletCo…...
回归预测 | MATLAB实现PSO-RF粒子群算法优化随机森林多输入单输出回归预测
回归预测 | MATLAB实现PSO-RF粒子群算法优化随机森林多输入单输出回归预测 目录回归预测 | MATLAB实现PSO-RF粒子群算法优化随机森林多输入单输出回归预测效果一览基本介绍程序设计参考资料效果一览 基本介绍 MATLAB实现PSO-RF粒子群算法优化随机森林多输入单输出回归预测 粒子…...
在小公司工作3年,从事软件测试5年了,才发现自己还是处于“初级“水平,是不是该放弃....
毕业前三年,从早到晚,加班到深夜,一年又一年,直至刚入职场的首个黄金三年过年都去了,而职位却仍在原地踏步。尽管感觉自己努力过,但是实际上,自身的能力从没得到过多少提升。 所以在无数个夜晚…...
CSS 容器查询:组件级响应式设计
CSS 容器查询:组件级响应式设计代码如诗,容器如画。让我们用容器查询的强大能力,创建真正自适应的组件。什么是容器查询? 容器查询(Container Queries)是 CSS 中一项革命性的特性,它允许我们根据…...
Topgrade性能优化技巧:提升大规模更新效率的5种方法
Topgrade性能优化技巧:提升大规模更新效率的5种方法 【免费下载链接】topgrade Upgrade all the things 项目地址: https://gitcode.com/gh_mirrors/top/topgrade Topgrade是一款强大的系统更新工具,它能自动检测并升级系统中的所有包管理器、编程…...
OpenClaw API配置失败?3步快速修复,免费额度高效利用
OpenClaw API配置失败?3步快速修复,免费额度高效利用引言 OpenClaw作为新一代数据采集平台,其API凭借高效稳定的特性已成为开发者首选的工具之一。但在实际接入过程中,配置失败问题频发,尤其对免费额度用户造成严重困扰…...
自指宇宙学形式化验证套件 (Coq‑SRU v1.2.0)
自指宇宙学形式化验证套件 (Coq‑SRU v1.2.0)技术摘要 正式整编版 项目标识:Coq Formalization of Self‑Referential Universe (Coq‑SRU) 版本:v1.2.0(对齐《世毫九自指宇宙学》理论第三部分) 代码仓库:https://git…...
2026届学术党必备的十大AI辅助写作助手解析与推荐
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek “降AI”是要借助技术手段,去降低文本里人工智能生成内容的可识别程度࿰…...
为什么数据质量成为人工智能领域最重要的问题
简而言之:传统的基于人工编写规则和被动检查的数据质量体系,从未针对智能体人工智能进行设计。到2026年,当自主代理处理错误数据时,没有人会介入以发现问题。那些在人工智能领域取得成功的组织,并非从更好的模型入手&a…...
解锁5大跨平台无线控制能力:QtScrcpy全方位使用指南
解锁5大跨平台无线控制能力:QtScrcpy全方位使用指南 【免费下载链接】QtScrcpy Android实时投屏软件,此应用程序提供USB(或通过TCP/IP)连接的Android设备的显示和控制。它不需要任何root访问权限 项目地址: https://gitcode.com/barry-ran/QtScrcpy …...
Delphi网络编程实战:UDP通信与多线程网络优化详解
前两篇文章分别讲解了Delphi中基于Indy组件的TCP点对点通信、HTTP/HTTPS接口交互,覆盖了可靠连接、Web对接两大常用场景。本篇将深入讲解UDP通信,同时补充多线程网络编程、数据传输防护、常见故障排查等进阶内容,补齐Delphi网络开发的核心模块…...
IDM开源工具免费使用指南:从安装到高级配置的完整实践
IDM开源工具免费使用指南:从安装到高级配置的完整实践 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Reset Script 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script Internet Download Manager(IDM&am…...
Mars3D与Cesium结合:3DTiles数据可视化全流程解析(含示例项目)
Mars3D与Cesium结合:3DTiles数据可视化全流程解析(含示例项目) 当我们需要在Web端实现高精度的三维地理数据可视化时,3DTiles格式已经成为行业标准。而将Mars3D与Cesium这两个强大的开源GIS引擎结合使用,可以发挥出11…...
