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

005-获取内存占用率

获取内存占用率

windows平台

在Windows环境下使用C++获取内存占用率,可以通过以下两种方式实现,分别针对系统整体和特定进程的内存监控:

一、获取系统整体内存占用率

核心函数:GlobalMemoryStatusEx
步骤:

  • 定义MEMORYSTATUSEX结构体并初始化dwLength字段
  • 调用函数获取内存信息
  • 通过dwMemoryLoad字段直接获取内存占用率百分比
#include <windows.h>

MEMORYSTATUSEX memInfo;
memInfo.dwLength  = sizeof(memInfo);
GlobalMemoryStatusEx(&memInfo);

DWORD memoryUsage = memInfo.dwMemoryLoad;  // 内存占用率百分比

二、获取特定进程内存占用

核心函数:GetProcessMemoryInfo

步骤:

  • 获取目标进程句柄(如当前进程用GetCurrentProcess())
  • 定义PROCESS_MEMORY_COUNTERS结构体
  • 调用函数获取内存信息
#include <windows.h>
#include <psapi.h>

PROCESS_MEMORY_COUNTERS pmc;
if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
    SIZE_T usedMem = pmc.WorkingSetSize; // 进程占用的物理内存
    SIZE_T totalMem = /* 总内存需通过GlobalMemoryStatusEx获取 */;
    double ratio = (usedMem * 100.0) / totalMem; // 计算占用率
}

三、关键注意事项

结构体初始化:
使用MEMORYSTATUSEX或PROCESS_MEMORY_COUNTERS时,必须正确初始化dwLength字段,否则函数调用失败。

权限问题:
访问其他进程内存需PROCESS_QUERY_INFORMATION和PROCESS_VM_READ权限,可通过OpenProcess函数获取。

四、扩展应用场景

  • 实时监控:结合定时器定期调用上述函数,实现动态内存监控界面
  • 性能分析:与CPU占用率(GetSystemTimes)、磁盘I/O等指标结合,构建完整的资源监控系统
  • 服务端优化:通过内存占用率数据调整服务资源分配策略

linux平台

在Linux环境下使用C++获取内存占用率,主要通过读取系统文件或调用系统接口实现。以下是几种常用方法及实现示例:

方法一:解析 /proc/meminfo 文件

系统内存信息存储在 /proc/meminfo 中,通过解析该文件获取内存总量和空闲量:

#include <fstream>
#include <string>
#include <unordered_map>

float get_memory_usage() {
    std::ifstream meminfo("/proc/meminfo");
    std::unordered_map<std::string, long> mem_data;
    std::string key;
    long value;

    while (meminfo >> key >> value) {
        meminfo.ignore(256,  '\n'); // 跳过单位(如 kB)
        mem_data[key] = value;
    }

    long total = mem_data["MemTotal:"];
    long available = mem_data["MemAvailable:"]; // 若系统不支持 MemAvailable,可用 MemFree + Buffers + Cached 替代
    long used = total - available;
    return (used * 100.0) / total;
}

说明:

MemAvailable 是更准确的可用内存指标(需内核3.14+),否则需计算 MemFree + Buffers + Cached 。
单位为 KB,计算时无需转换。

方法二:使用 sysinfo() 系统调用

通过 sysinfo 函数直接获取内存信息:

#include <sys/sysinfo.h>

float get_memory_usage() {
    struct sysinfo info;
    sysinfo(&info);

    long total = info.totalram  * info.mem_unit; 
    long free = info.freeram  * info.mem_unit; 
    long used = total - free;

    return (used * 100.0) / total;
}

说明:

  • sysinfo() 提供更直接的系统内存统计,无需文件解析 。
  • mem_unit 是内存单位(通常为字节),需手动计算总内存和空闲内存。
  • 扩展:获取进程内存占用(物理内存)
  • 若需获取特定进程的内存占用,可解析 /proc/[pid]/status:
#include <fstream>
#include <string>

long get_process_memory(int pid) {
    std::ifstream status("/proc/" + std::to_string(pid) + "/status");
    std::string line;
    
    while (std::getline(status, line)) {
        if (line.find("VmRSS")  != std::string::npos) { // 物理内存占用
            long mem_kb;
            sscanf(line.c_str(), "VmRSS: %ld kB", &mem_kb);
            return mem_kb * 1024; // 转换为字节
        }
    }
    return -1;
}

说明:

VmRSS 表示进程实际使用的物理内存 。
单位为 KB,需转换为字节。
注意事项

  • 权限问题:需确保程序有权限读取 /proc 目录下的文件。
  • 实时性:/proc/meminfo 和 sysinfo() 的数据是动态更新的。
  • 单位转换:不同方法可能涉及 KB 或字节单位,需统一计算。

macOS平台

在 macOS 环境下通过 C++ 获取内存占用率,需要结合系统级 API 和 Mach 内核接口。以下是具体实现方法及核心知识点总结:

一、系统整体内存占用率

实现原理

  • 通过 sysctl 和 host_statistics 接口获取物理内存总量和已使用量:
#include <mach/mach_host.h>
#include <sys/sysctl.h>

// 获取物理内存总量
uint64_t get_total_memory() {
    int mib[2]()  = {CTL_HW, HW_MEMSIZE};
    uint64_t total_mem = 0;
    size_t len = sizeof(total_mem);
    sysctl(mib, 2, &total_mem, &len, NULL, 0);
    return total_mem;
}

// 计算内存占用率
float get_memory_usage() {
    vm_size_t page_size;
    mach_port_t host_port = mach_host_self();
    mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
    vm_statistics_data_t vm_stat;
    
    host_page_size(host_port, &page_size);
    host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
    
    uint64_t total_mem = get_total_memory();
    uint64_t used_mem = (vm_stat.active_count  + vm_stat.wire_count)  * page_size;
    return (float)used_mem / total_mem * 100.0f;
}

二、进程级内存占用

实现原理

  • 通过 Mach 任务接口获取进程的驻留内存(RSS):
#include <mach/mach_init.h>
#include <mach/task.h>

size_t get_process_memory_usage() {
    task_t task = mach_task_self();
    struct mach_task_basic_info info;
    mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT;
    
    if (task_info(task, MACH_TASK_BASIC_INFO, (task_info_t)&info, &count) == KERN_SUCCESS) {
        return info.resident_size;  // 返回单位为字节
    }
    return 0;
}

三、关键知识点

  • Mach 内核接口
    macOS 内存管理基于 Mach 微内核,需使用 mach_host.h 和 mach/task.h 中的函数获取内存统计信息 。

  • 内存计算逻辑
    系统内存占用率 = (活跃内存 + 固定内存) / 总物理内存。活跃内存(active_count)和固定内存(wire_count)反映当前使用状态 。

  • 性能优化
    频繁调用 host_statistics 可能影响性能,建议间隔 1-2 秒采样一次 。

四、扩展应用场景

  • 系统监控工具:实时显示内存曲线(参考 的 QT 实现)
  • 性能分析:结合 CPU 占用率监控(需使用 host_processor_info 接口)
  • 自动化测试:记录内存泄漏数据(长期监控进程 RSS 变化)

完整代码

Github

作者郑天佐
邮箱zhengtianzuo06@163.com
主页http://www.zhengtianzuo.com
githubhttps://github.com/zhengtianzuo

http://www.kler.cn/a/577580.html

相关文章:

  • Go学习笔记:基础语法2
  • 六十天前端强化训练之第十四天之深入理解JavaScript异步编程
  • 【前端】webstorm创建一个导航页面:HTML、CSS 和 JavaScript 的结合
  • 神经网络|(十五)|霍普菲尔德神经网络-Storkey 训练
  • 行为模式---责任链模式
  • 气膜科技赋能冰雪产业,开启可持续发展新路径—轻空间
  • mybatis-plus+springboot3项目实现分页
  • RK Android14 应用打开蓝牙时去掉确认提示
  • GESP2024年6月认证C++三级( 第三部分编程题(2)寻找倍数)
  • 整理一下高级设施农业栽培学这门课程的所有知识点
  • Kafka的各个组件说明
  • 韩国互联网巨头 NAVER 如何借助 StarRocks 实现实时数据洞察
  • 基于Matlab的人脸识别的二维PCA
  • 基于 Qwen2.5-14B + Elasticsearch RAG 的大数据知识库智能问答系统
  • uniapp使用蓝牙,usb,局域网,打印机打印
  • 【音视频】ffmpeg命令提取音视频数据
  • AI 驱动的软件测试革命:从自动化到智能化的进阶之路
  • Node.js入门笔记2---下载安装Node.js
  • 专门为高速连续扫描设计的TDI工业相机
  • 项目实战--网页五子棋(对战功能)(9)