当前位置: 首页 > news >正文

C/C++中的虚拟内存

文章目录

  • 一、虚拟内存
  • 二、C中的虚拟内存分配模型
  • 三、C++中的虚拟内存分配模型
  • 四、堆区和栈区的区别


一、虚拟内存

虚拟内存是一种实现在计算机软硬件之间的内存管理技术,它将程序使用到的内存地址(虚拟地址)映射到计算机内存中的物理地址,虚拟内存使得应用程序从繁琐的内存空间管理中解放出来,通过内存隔离提高了内存安全性。

虚拟内存地址通常是连续的地址空间,由操作系统的内存管理模块控制,在触发缺页中断时利用分页技术将实际的物理内存分配给虚拟内存。同时虚拟内存的空间大小远超出实际物理内存的大小,虚拟内存技术使得进程可以使用比物理内存大得多的内存空间。


二、C中的虚拟内存分配模型

在这里插入图片描述

C语言中一个进程的内存映像从低地址开始分为正文段、初始化数据段、未初始化数据段、堆区、栈区五大部分:

  1. Text段:Text段是指用来存放程序执行代码的一块内存区域,是二进制文件(或者说处理器的机器指令)在内存中的映像。当然也有可能包含一些只读的常数变量,例如字符串常量等。这部分区域的大小在程序运行前就已经确定,并且通常只允许进行读操作,向Text段写会导致Segmention Fault。
  2. Data段:Data段是指存放程序中已经初始化的全局变量和静态变量的一块内存区域。Data段并不是匿名的,而是映射了程序二进制文件中在编译时就已初始化的数据,由程序初始化
  3. BSS段:BSS段存放了未初始化的全局变量和静态变量由操作系统初始化(清零),且是匿名的不映射任何文件,不占用外存空间,只在运行时占用内存。注意,这里的未初始化指的是没有显示初始化,因为全局变量和静态变量会自动隐式初始化为0,但我们没有必要把这些0都存储起来,从而节省外存空间,这也是BSS段的主要作用。
  4. 堆区:堆提供了程序运行时的内存分配,堆内存的生命周期在函数之外,大部分语言都提供了堆内存管理函数, 如C语言的malloc()free(),因此堆区由用户管理,可控性强。如果当前堆的内存足够程序使用,则不需要与内核交互,在当前堆中寻找可用内存就行,否则的话需要调用brk()系统调用向内核申请空间,堆内存分配的算法非常复杂,既要保证内存分配的实时和快速,又要尽量避免堆中出现过多碎片,由此也就引申出了操作系统中的一系列内存分配算法与分配策略,如FF、BF、WF、NF等。
  5. 栈区:栈保存了局部变量、函数形参、返回值等,调用一个新的函数会在栈上创建一个新的栈帧,当函数返回时这个栈帧会被自动销毁。一个栈帧包括:函数的返回地址和参数、临时变量(包括函数的非静态局部变量以及编译器自动生成的其他临时变量)、栈帧状态值(EBP和ESP,划定了这个函数的栈帧的范围)。栈的空间分配与堆略有不同,当栈空间用尽后继续push会触发栈空间的扩展,导致Page Fault,然后在内核中调用expand_stack(),该函数调用acct_stack_growth()来判断是否可以增长栈空间,如果当前栈空间的大小小于RLIMIT_STACK,则可以继续增长栈空间,该过程由内核完成进程不会感知到。当用户的栈空间已经达到允许的最大值时,内核会给进程发送一个Segmentation Fault信号终止该进程,因此进程的栈空间只会增大不会缩小。

三、C++中的虚拟内存分配模型

C++中的虚拟内存分配与C中大体上相似,只在细节处略有不同:

  1. 常量区:常量区是一块比较特殊的存储区,专门用来存储那些由const修饰的变量以及常量字符串等不能被修改的常量,在程序结束后由系统释放。
  2. 全局/静态存储区:存放全局变量和静态变量,程序一经编译该区域就会存在。在C++中,由于编译器会对全局变量和静态变量进行自动初始化并赋值,所以并没有像C中一样对初始化变量和未初始化变量进行区分。全局/静态存储区会在程序结束后由系统释放。
  3. 自由存储区自由存储区是通过malloc/calloc/realloc分配的内存,并需要通过free释放。如果程序员没有进行free操作,则会造成内存泄露,并在程序结束时由OS进行内存回收。
  4. 堆区:与C中不同的是,C++中堆是由new申请的内存,并由delete或delete[]释放
  5. 栈区:保存函数中的局部变量、函数参数以及返回值。由编译器负责分配释放,函数结束栈变量也随之失效。

四、堆区和栈区的区别

堆区栈区
管理者由用户管理,可控性强由系统管理,分配效率高
地址扩展从低地址向高地址扩展从高地址向低地址扩展
申请后的系统响应如果当前堆的内存足够程序使用,则不需要与内核交互,继续在当前堆中寻找可用内存就行。否则的话需要调用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之间有多少个素数&#xff0c;并输出所有素数。 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开发实战技巧】系列&#xff08;一&#xff09;:关于SQL不得不说的那些事 【SQL开发实战技巧】系列&#xff08;二&#xff09;&#xff1a;简单单表查询 【SQL开发实战技巧】系列&#xff08;三&#xff09;&#xff1a;SQL排序的那些事 【SQL开发实战技巧…...

springBoot自动配置过程介绍

什么是自动配置 以前整合spring mybatis框架时候&#xff0c;需要加很多的bean, 比如说sqlSessionFactory等等 现在springboot帮我们干了&#xff0c;我们只需要引入对应的starter就可以了。 springBoot可以帮我们配置好了一些bean. 如mysql, mogondb相关操作等等&#xff…...

PostgreSQL最后的救命稻草 — pg_resetwal

pg_resetwal— 重置 PostgreSQL 数据库集群的预写日志和其他控制信息 适用版本&#xff1a;PostgreSQL 12/13/14/15语法 pg_resetwal [ -f | --force ] [ -n | --dry-run ] [option...] [ -D | --pgdata ]datadir描述pg_resetwal清除预写日志 WAL&#xff0c;并可选地重置pg_c…...

彻底关闭Windows更新

一、关闭Windows Update服务 1、按“Windows R”键&#xff0c;打开运行对话框&#xff0c;并输入“services.msc”&#xff0c;然后再单击“确定”。 2、在弹出的服务窗口中&#xff0c;找到“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顺序调用函数并抛出异常 场景 新建或者编辑时&#xff0c;一个页面中存在多个表单&#xff0c;每个表单都有单独进行表单验证。点击提交时&#xff0c;若有一个表单校验失败&#xff0c;则不能提交。 ps&#xff1a;为啥不放在一个表单中&#xff1f; (…...

Python实现GWO智能灰狼优化算法优化随机森林分类模型(RandomForestClassifier算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 灰狼优化算法(GWO)&#xff0c;由澳大利亚格里菲斯大学学者 Mirjalili 等人于2014年提出来的一种群智能…...

从redis到epoll到mmap

redis为什么这么快&#xff1f; 比较容易答出的答案 1)纯粹的内存操作 2)单线程操作,不用考虑线程切换 其他优势 3)I/O 多路复用,使用epoll 4)Reactor 设计模式 I/O 多路复用有三种 select、poll、epoll select&#xff1a;使用数组存储轮询 poll&#xff1a;使用链表轮询 epo…...

STM32CubeMX快速构造工程模板(一)

STM32CubeMX作为一个免费开源的软件,能够可视化配置STM32或其他产品硬件资源,能过快速地构造工程模板,很是方便!!! 目录 STM32CubeMX快速构造工程模板 首先第一步,打开软件-点击按钮-输入型号-双击打开。...

Java Web中的ServletContext对象

目录 ServletContext对象 获取上下文初始化参数的相关方法 创建ServletContext对象 1&#xff09;通过 GenericServlet 提供的 getServletContext() 方法 2&#xff09;通过 ServletConfig 提供的 getServletContext() 方法 3&#xff09;通过 HttpSession 提供的 getServletCo…...

回归预测 | MATLAB实现PSO-RF粒子群算法优化随机森林多输入单输出回归预测

回归预测 | MATLAB实现PSO-RF粒子群算法优化随机森林多输入单输出回归预测 目录回归预测 | MATLAB实现PSO-RF粒子群算法优化随机森林多输入单输出回归预测效果一览基本介绍程序设计参考资料效果一览 基本介绍 MATLAB实现PSO-RF粒子群算法优化随机森林多输入单输出回归预测 粒子…...

在小公司工作3年,从事软件测试5年了,才发现自己还是处于“初级“水平,是不是该放弃....

毕业前三年&#xff0c;从早到晚&#xff0c;加班到深夜&#xff0c;一年又一年&#xff0c;直至刚入职场的首个黄金三年过年都去了&#xff0c;而职位却仍在原地踏步。尽管感觉自己努力过&#xff0c;但是实际上&#xff0c;自身的能力从没得到过多少提升。 所以在无数个夜晚…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中&#xff0c;如工厂高危作业区、医院手术室、公共场景等&#xff0c;人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式&#xff0c;存在效率低、覆盖面不足、判断主观性强等问题&#xff0c;难以满足对人员打手机行为精…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...