c++中如何获取程序运行过程中的内存占用_c++监控内存方法【详解】

发布时间 - 2026-01-31 00:00:00    点击率:
Linux下读取/proc/self/status的VmRSS字段(单位KB)最轻量常用,反映真实物理内存占用;Windows用GetProcessMemoryInfo获取WorkingSetSize,二者等价;避免使用mallinfo等堆内指标,因其严重低估真实内存。

Linux 下用 /proc/self/status 读取当前进程 RSS 内存

最轻量、最常用的方法是读取 /proc/self/status 文件中的 VmRSS 字段,它代表当前进程实际占用的物理内存(单位:KB)。这个值不包含 swap,也不含共享内存重复计算,适合监控真实内存压力。

注意:/proc 是 Linux 特有接口,Windows 不可用;且需确保程序有读取该文件权限(通常都有)。

  • VmRSS 值会滞后于 malloc/free 调用,因为内核按页回收,不是立即释放
  • 不要解析 VmSize(虚拟内存大小),它包含未分配的 mmap 区域和保留地址空间,不能反映真实内存压力
  • 建议每秒读取不超过 10 次,频繁读 /proc/self/status 会产生轻微 I/O 开销
FILE* f = fopen("/proc/self/status", "r");
if (f) {
    char line[256];
    while (fgets(line, sizeof(line), f)) {
        if (strncmp(line, "VmRSS:", 6) == 0) {
            long rss_kb;
  

sscanf(line, "VmRSS: %ld kB", &rss_kb); printf("RSS: %ld KB\n", rss_kb); break; } } fclose(f); }

Windows 下用 GetProcessMemoryInfo 获取工作集大小

Windows 对应方案是调用 psapi.h 中的 GetProcessMemoryInfo,读取 PROCESS_MEMORY_COUNTERS::WorkingSetSize。它等价于 Linux 的 VmRSS,即当前驻留在物理内存中的字节数。

需要链接 psapi.lib,并在项目中定义 PSAPI_VERSION 1(否则可能返回 0)。

  • WorkingSetSize 包含私有内存 + 共享内存(如系统 DLL),但不含已换出页面
  • 如果函数返回 FALSE,检查是否漏加 #pragma comment(lib, "psapi.lib") 或未启用 PSAPI_VERSION
  • 避免在多线程高频调用中反复打开/关闭当前进程句柄;复用 GetCurrentProcess() 返回的句柄即可
#include 
#include 
#pragma comment(lib, "psapi.lib")

void print_memory_usage() { PROCESS_MEMORY_COUNTERS pmc; if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) { printf("WorkingSetSize: %zu KB\n", pmc.WorkingSetSize / 1024); } }

跨平台封装时慎用 mallinfomalloc_stats

mallinfo(glibc)和 malloc_stats 输出的是堆管理器内部视图,不是 OS 看到的真实内存。它们只统计 malloc 系统调用分配的 heap 区域,忽略 mmap 分配的大块内存(如 std::vector 超过阈值后自动切到 mmap)、静态数据、栈、共享库等。

因此,这些接口容易严重低估真实内存占用,尤其在大量使用 std::stringstd::vector 或第三方库(如 protobuf、OpenCV)时。

  • mallinfo().uordblks 只反映 glibc malloc arena 中已分配但未 free 的字节数
  • malloc_stats() 输出到 stderr,无法直接捕获,且格式不固定,不适合自动化解析
  • C++17 起,std::allocator 不保证调用 malloc,部分实现走 mmapmallinfo 完全不可见

监控精度与采样频率的实际取舍

内存监控不是越细越好。高频采样(如每毫秒)本身就会增加调度开销和锁竞争(尤其是 /proc 文件读取或 Windows PSAPI 调用),反而干扰被测程序行为。

真实场景下,推荐按需分层:

  • 调试阶段:每 100–500ms 采样一次,配合关键路径打点(如函数入口/出口)
  • 线上服务:每 5–30 秒聚合一次,写入日志或上报 metrics,避免 IO 毛刺
  • OOM 分析:配合 setrlimit(RLIMIT_AS) 或 cgroup memory.max(Linux)做硬限制,比事后查 RSS 更可靠

真正难的不是“怎么读内存”,而是判断哪个值能对应你关心的问题——是防止 OOM?定位泄漏?还是优化缓存命中率?选错指标,数据再准也没用。


# linux  # windows  # 字节  # 虚拟内存  #   # c++  # win  # 内存占用  # String  # 封装  # 接口  #   # 线程  # 多线程  # opencv  # 自动化  # 句柄  # 不含  # 的是  # 最轻  # 就会  # 都有  # 尤其是  # 并在  # 线上  # 不超过 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何与Docker(Sail)协同开发?(环境搭建教程)  东莞专业网站制作公司有哪些,东莞招聘网站哪个好?  为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】  深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?  如何用搬瓦工VPS快速搭建个人网站?  如何快速搭建高效WAP手机网站吸引移动用户?  如何用已有域名快速搭建网站?  HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】  中国移动官方网站首页入口 中国移动官网网页登录  北京企业网站设计制作公司,北京铁路集团官方网站?  jQuery中的100个技巧汇总  通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】  千库网官网入口推荐 千库网设计创意平台入口  Python文件操作最佳实践_稳定性说明【指导】  Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】  Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】  Internet Explorer官网直接进入 IE浏览器在线体验版网址  如何在IIS中配置站点IP、端口及主机头?  如何快速搭建支持数据库操作的智能建站平台?  Laravel怎么自定义错误页面_Laravel修改404和500页面模板  Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧  phpredis提高消息队列的实时性方法(推荐)  猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】  Swift中switch语句区间和元组模式匹配  EditPlus中的正则表达式 实战(1)  Laravel怎么实现支付功能_Laravel集成支付宝微信支付  微信小程序 HTTPS报错整理常见问题及解决方案  Laravel如何自定义分页视图?(Pagination示例)  Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】  Laravel Octane如何提升性能_使用Laravel Octane加速你的应用  linux写shell需要注意的问题(必看)  bing浏览器学术搜索入口_bing学术文献检索地址  Laravel如何实现事件和监听器?(Event & Listener实战)  小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像  Windows Hello人脸识别突然无法使用  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  Python函数文档自动校验_规范解析【教程】  悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音  如何在Windows服务器上快速搭建网站?  edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】  油猴 教程,油猴搜脚本为什么会网页无法显示?  Laravel Debugbar怎么安装_Laravel调试工具栏配置指南  香港服务器建站指南:免备案优势与SEO优化技巧全解析  Laravel集合Collection怎么用_Laravel集合常用函数详解  js实现获取鼠标当前的位置  C++用Dijkstra(迪杰斯特拉)算法求最短路径  php静态变量怎么调试_php静态变量作用域调试技巧【解答】  宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法  如何用西部建站助手快速创建专业网站?  Laravel事件监听器怎么写_Laravel Event和Listener使用教程