尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
【QT入门到晋级】内存
前言本文从“在C/C开发时选用哪种内存处理方式较好”的角度聊聊内存的使用。主要还是站在需要开发后台功能的QT开发者的角度来写的总结笔记。内存分布我们开发的应用程序运行时为了确保确保系统稳定性通常应用程序是在用户态下运行只能访问操作系统为其分配的‌用户空间内存‌。临时变量、局部变量等临时值通常存储在用户态的栈空间或寄存器中全局变量、静态常量、静态数组等生命周期为整个程序运行期的通常存储在用户态的静态存储区数据段或BSS段动态数组如new、malloc、calloc、realloc等申请的内存、 STL容器(vector、list、map) 等通常存储在用户态的堆空间中通过malloc或new申请动态内存时尝试从用户态的堆内存池中分配内存若用户态堆中有足够空闲内存块则直接返回给应用程序若用户态的堆内存不足时C库会通过系统调用如brk或mmap向内核申请扩展堆空间应用程序不需要关注此操作。通过‌内存映射文件‌技术(mmap)申请的内核动态内存内核会为用户态应用进程分配虚拟地址空间这个虚拟机地址空间是在用户态地址空间中分配并建立与物理内存或文件的映射关系。以下是单个应用进程3类分布区对比声明以下表格来源于AI辅助创作‌特性‌‌栈(Stack)‌‌静态存储区(Static Area)‌‌堆(Heap)‌‌典型应用场景‌临时变量、局部变量全局变量、静态常量、静态数组动态数据、大对象‌分配方式‌编译器自动分配/释放调整栈指针编译期固定地址分配运行时动态分配malloc/new‌访问速度‌最快仅次于CPU寄存器次之直接寻址最慢间接寻址‌生命周期函数调用周期程序运行周期手动控制或GC管理‌内存连续性‌连续存储连续存储非连续链表结构‌大小范围‌Linux‌: 2-10MBWindows‌: 1-8MB单变量/数组不超过几百MB理论是所有系统剩余虚拟内存申请越多碎片越严重‌管理开销‌无自动管理无编译期确定高需维护空闲链表/内存池‌线程安全‌线程独占无需同步可能需同步全局共享需同步多线程共享‌碎片问题‌无无易产生碎片‌分配失败后果‌栈溢出程序崩溃编译期错误返回NULL需错误处理开发运用栈的应用栈空间是最小的也是执行最快的适合存放‌小型、生命周期短且大小固定的数据因为有大小限制如果申请大数据容易导致程序崩溃例如int arr[1000000]约4MB可能超出栈默认大小引发栈溢出。以下通过读取文件内容的场景来对比//正确方式不管文件有多大每次读取1KB到栈中 std::ifstream file(large_file.bin, std::ios::binary); char buff[1024]; // 1KB栈缓冲区 while (file.read(buff, sizeof(buff))) { // 处理当前块buff中数据 } //错误方式10MB栈缓冲区导致程序崩溃 std::ifstream file(large_file.bin, std::ios::binary); char buff[1024*1024*10]; // 10MB栈缓冲区 while (file.read(buff, sizeof(buff))) { // 处理当前块buff中数据 }如果硬要申请很多的数据缓存可以把数组char buff[1024*1024*10];搬到外面作为静态数组用或者改成vector(动态内存)方式来用下面给出改成动态内存方式的样例const size_t buffer_size 1024 * 1024 * 20; // 20MB缓冲区 std::vectorchar buff(buffer_size); // 堆分配缓冲区 std::ifstream file(large_file.bin, std::ios::binary | std::ios::ate); while (file.read(buff.data(), sizeof(buff))) { // 处理当前块buff中数据 }总结临时变量、局部变量不能申请太大的数组缓存主要是关注大数组或者是包含大数组的结构体即可。静态存储区的应用静态存储区与栈很接近运行效率稍微比栈低但空间比栈大而且作用域是整个全局如果频繁要用到某个常量/变量/数组那么就适合设置为全局变量、静态常量、静态数组。全局变量、静态常量太常用了这里举个静态数组的场景处理指定目录下存在待入库到mysql的文件// 数据结构体 struct stCollectMsg { int id; char name[64]; double value; char timestamp[20]; }; const int BATCH_SIZE 100; stCollectMsg sqldata[BATCH_SIZE]; // 静态数组 // 文件读取函数 void ReadFile(const char* filename) { std::ifstream file(filename, std::ios::binary); int current_count 0; while (!file.eof()) { //读取数据 file.read((char*)sqldata[current_count], sizeof(stCollectMsg)); if (file.gcount() sizeof(stCollectMsg)) { //数量时把数据插入数据库 if (current_count BATCH_SIZE) { InsertData(conn, sqldata, current_count); current_count 0; } } } // 处理剩余数据 if (current_count 0) { InsertData(conn, sqldata, current_count); } } // 数据入库函数 void InsertData(MYSQL* conn, stCollectMsg* data, int count) { std::string query INSERT INTO collect_data (id, name, value, timestamp) VALUES ; for (int i 0; i count; i) { query ( std::to_string(data[i].id) , data[i].name , std::to_string(data[i].value) , data[i].timestamp ); if (i ! count - 1) query ,; } if (mysql_query(conn, query.c_str())) { std::cerr 入库失败: mysql_error(conn) std::endl; } }组装多条数据一次入库比一条一条入库效率快很多类似的场景很多。堆的应用静态数组能做的申请堆内存的动态数组也能做区别是堆上申请的内存是不连续的导致整体性能没有动态数组和静态数组效率快。但是堆更灵活也更大适合大对象数据以及规模大的数据量处理。比如视频类数据都是以G为单位最好放在动态内存中。虚拟地址空间使用mmap进行内存映射时用户空间会创建虚拟地址区域同时与物理内存建立映射关系应用进程以访问虚拟地址的方式来访问真实的物理内存。以下通过与动态内存对比来加深了解声明以下表格来源于AI辅助创作对比维度mmap内存映射动态内存分配(malloc/free)‌工作原理‌将文件/设备映射到进程虚拟地址空间建立直接访问通道通过系统调用从堆(heap)分配内存块返回可操作指针‌内存来源‌文件数据或匿名映射区(不关联文件)堆内存空间‌系统开销‌建立映射开销较大(需修改页表)适合长期使用的内存区域分配/释放操作轻量适合频繁变动的内存需求‌管理机制‌由操作系统内核管理映射关系自动处理页错误需程序员手动管理分配/释放依赖内存管理器实现(如ptmalloc、jemalloc)‌性能特点‌• 大文件访问减少拷贝开销• 缺页中断影响随机访问性能• 小内存分配效率高• 频繁分配/释放可能产生碎片‌内存限制‌受虚拟地址空间限制(32位系统约3GB用户空间)受物理内存swap空间限制‌线程安全‌映射区域自动共享需额外同步机制分配器本身线程安全但使用需加锁‌典型问题‌• 内存映射对齐要求(通常4KB)• msync同步策略选择• 内存泄漏风险• use-after-free漏洞• 碎片化导致分配失败‌优势场景‌• 大文件随机访问(数据库索引)• 进程间共享内存• 零拷贝数据传输• 灵活分配任意大小内存• 实时内存需求处理• 短生命周期对象‌适用场景‌• 数据库引擎• 大型媒体文件处理• 进程间通信• 动态数据结构• 临时缓冲区• 运行时确定大小的对象总结mmap在内存映射时开销比较大处理小数量的内存/数据性能较低其优势场景是适合大文件读写以及多个进程共享一段内存。比如一段高清监控视频可以结合共享内存内存映射提供查看进程、AI分析进程、质量分析进程等多个进程同时访问这种设计方式比每个进程自己加载一段高清监控视频到自己的动态区域后再进行分析的设计方式节省内存以及节省IO操作的开销。以下给出内存映射与常规IO操作对比表声明以下表格来源于AI辅助创作对比维度mmap操作read/write操作工作原理将文件直接映射到进程地址空间通过内核缓冲区进行数据中转优势场景• 随机访问大文件数据库/B树• 频繁访问相同文件区域• 进程间共享内存• 顺序读写日志文件• 流式处理视频编码• 精确控制I/O时序性能表现• 大文件随机访问快3-5倍• 零拷贝网络传输优势• 小文件操作快20-30%• 流式数据吞吐量稳定内存影响可能引发大量缺页中断需预加载策略内核缓冲区可控可调节buffer大小数据安全依赖msync同步默认异步写入同步写入保证数据持久化适用文件大小1MB文件效益明显1MB文件效率更优多进程协作天然支持MAP_SHARED需额外IPC机制复杂度需处理页对齐问题4KB倍数编程模型简单直接典型应用• 数据库引擎• 机器学习模型加载• 地理空间数据处理• 日志收集系统• 压缩包处理• 网络协议栈实现系统限制受限于虚拟内存空间32位系统最大2-3GB仅受物理存储限制
RELATED

相关推荐

如何快速上手安卓投屏与控制:Scrcpy 完整指南

如何快速上手安卓投屏与控制:Scrcpy 完整指南

如何快速上手安卓投屏与控制:Scrcpy 完整指南 【免费下载链接】scrcpy Display and control your Android device 项目地址: https://gitcode.com/GitHub_Trending/sc/scrcpy 把手机画面投到电脑屏幕,还能直接用键盘鼠标操作手机——Scrcpy&#…

📅 2026/10/22 1:21:31
SteamTradingSiteTracker 上手拆解:一条挂刀比例数据是怎么从爬虫算到界面上的

SteamTradingSiteTracker 上手拆解:一条挂刀比例数据是怎么从爬虫算到界面上的

SteamTradingSiteTracker 上手拆解:一条挂刀比例数据是怎么从爬虫算到界面上的 【免费下载链接】SteamTradingSiteTracker Steam 挂刀行情站 —— 24小时更新的 BUFF & IGXE & C5 & UUYP & ECO 挂刀比例数据 | Track cheap Steam Community Market …

📅 2026/10/22 1:16:31
如何在安卓手机上快速安装LibreCuts:F-Droid、Obtainium与GitHub三渠道完整指南

如何在安卓手机上快速安装LibreCuts:F-Droid、Obtainium与GitHub三渠道完整指南

【免费下载链接】LibreCuts LibreCuts is a free, open-source video editor for Android that prioritizes simplicity and efficiency. 项目地址: https://gitcode.com/gh_mirrors/li/LibreCuts 点击查看 免费下载 LibreCuts 是一款免费、开源、无广告的安卓视频…

📅 2026/10/22 1:16:31
MORE NEWS

更多资讯

📰

配书资源改造与代码复现:从教案整理到版本管理的备课实战

简介:《程序设计基础(第3版)》陈娟编著的配书资源,将电子教案与源代码完整打包,面向高校计算机科学与技术、软件工程专业师生,以及培训班学员和自学者,旨在弥补课堂教学素材不足、缺乏可运行示例…

📰

TCP聊天室:网络编程入门的黄金练手项目

1. 项目概述:为什么一个“基于TCP网络通信的聊天室”至今仍是入门网络编程的黄金练手项目你可能在某次技术分享里听过这句话:“想真正搞懂网络通信,别急着上WebSocket或gRPC,先亲手写一个能跑通的TCP聊天室。”这不是情怀滤镜&…

📰

网格划分源码实战:从几何输入到质量检查全流程解析

简介:面向计算机图形学、数值计算与并行计算领域的开发者,这份源码以C实现网格划分核心算法,覆盖从空间离散、网格生成到动态细化的主要流程,解决如何高效划分复杂几何体的问题,适合不同技能层的开发者作为算法学习与项…

📰

扩散模型图像编辑如何更忠实?奖励建模与强化学习实战解析

训练一个会说"不对"的裁判,往往比让选手自己意识到错在哪更有效。这句话是我消化完Trust Your Critic: Robust Reward Modeling and Reinforcement Learning for Faithful Image Editing这个研究主题后最直接的反应。它讨论的是一个非常实际的问题&#x…

📰

信息熵、交叉熵与KL散度:机器学习损失函数的信息论本质

1. 从"天气预报"说起:信息量凭什么用对数来度量先讲一件我去年做模型时遇到的怪事。当时在调一个多分类的模型,验证集准确率卡在 87% 上不去。我同事看了一眼损失曲线,说"你把标签做平滑试试"。我那时候只把交叉熵当个公…

📰

VC++远程控制源码实战:Winsock通信与MFC功能解析

简介:用Visual C开发远程控制软件的源码包,适合需要学习Windows网络编程和系统控制原理的初学者及中级开发者,能够帮助快速搭建基于TCP/IP的远程控制原型。压缩包内共30个文件,其中10个头文件与8个C源代码文件构成了程序主体&…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬