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

Windows 获取内存 API 汇总及使用方法

Windows 获取内存 API 汇总及使用方法

本文示例代码:https://gitee.com/langshanglibie/windows-memory-api
运行结果

一、获取系统内存(物理内存、虚拟内存)

GlobalMemoryStatusEx

  • MEMORYSTATUSEX
MEMORYSTATUSEX statex;
statex.dwLength = sizeof(statex);
GlobalMemoryStatusEx(&statex); // GlobalMemoryStatusEx 只能针对当前进程调用,不能针对指定进程调用,因为没法传递进程句柄printf("%*ld%% - 物理内存使用率\n", WIDTH, statex.dwMemoryLoad);printf("\n");printf("%*.2f GB - 物理内存总量\n", WIDTH, statex.ullTotalPhys / GB);
printf("%*.2f GB - 已经使用的物理内存总量\n", WIDTH, (statex.ullTotalPhys - statex.ullAvailPhys) / GB);
printf("%*.2f GB - 剩余物理内存总量\n", WIDTH, statex.ullAvailPhys / GB);printf("\n");printf("%*.2f GB - 可提交最大内存总量(物理内存 + pagefile)\n", WIDTH, statex.ullTotalPageFile / GB); // 等同于 PERFORMANCE_INFORMATION.CommitLimit
printf("%*.2f GB - 已经提交内存总量(物理内存 + pagefile)\n", WIDTH, (statex.ullTotalPageFile - statex.ullAvailPageFile) / GB);
printf("%*.2f GB - 剩余内存总量(物理内存 + pagefile)\n", WIDTH, statex.ullAvailPageFile / GB); // 等同于 PERFORMANCE_INFORMATION.CommitTotalprintf("\n");printf("%*.2f GB - 当前进程用户模式虚拟内存总量\n", WIDTH, statex.ullTotalVirtual / GB);
printf("%*.2f MB - 当前进程已经使用的用户模式虚拟内存总量\n", WIDTH, (statex.ullTotalVirtual - statex.ullAvailVirtual) / MB);
printf("%*.2f GB - 当前进程剩余用户模式虚拟内存总量\n", WIDTH, statex.ullAvailVirtual / GB);printf("\n");printf("%*.2f GB - AvailExtendedVirtual(Reserved, is always 0)\n", WIDTH, statex.ullAvailExtendedVirtual / GB);

GetPhysicallyInstalledSystemMemory

The GetPhysicallyInstalledSystemMemory function retrieves the amount of physically installed RAM from the computer’s SMBIOS firmware tables. This can differ from the amount reported by the GlobalMemoryStatusEx function, which sets the ullTotalPhys member of the MEMORYSTATUSEX structure to the amount of physical memory that is available for the operating system to use. The amount of memory available to the operating system can be less than the amount of memory physically installed in the computer because the BIOS and some drivers may reserve memory as I/O regions for memory-mapped devices, making the memory unavailable to the operating system and applications.
译文:
GetPhysicalyInstalledSystemMemory函数从计算机的SMBIOS固件表中检索物理安装的RAM数量。这可能与GlobalMemoryStatusEx函数报告的数量不同,该函数将MEMORYSTATUSEX结构的ullTotalPhys成员设置为操作系统可使用的物理内存量。操作系统可用的内存量可能小于物理安装在计算机中的内存量,因为BIOS和一些驱动程序可能会将内存保留为内存映射设备的I/O区域,从而使内存对操作系统和应用程序不可用。

ULONGLONG totalMemoryInKilobytes = 0;
GetPhysicallyInstalledSystemMemory(&totalMemoryInKilobytes);
printf("%*.2f GB - 物理内存总量(电脑安装的)\n", WIDTH, totalMemoryInKilobytes / MB);

GetPerformanceInfo

  • PERFORMANCE_INFORMATION
PERFORMANCE_INFORMATION pi = {sizeof(PERFORMANCE_INFORMATION)};
::GetPerformanceInfo(&pi, sizeof(PERFORMANCE_INFORMATION));
// 对应任务管理器【性能】->【已提交】
printf("%*.2f GB - 可提交最大内存总量(物理内存 + pagefile)\n", WIDTH, 1.0 * pi.CommitLimit * pi.PageSize / GB); // 乘以 1.0 换为 double,否则数值越界被截断!
printf("%*.2f GB - 已经提交内存总量(物理内存 + pagefile)\n", WIDTH, 1.0 * pi.CommitTotal * pi.PageSize / GB);
printf("%*.2f GB - 剩余内存总量(物理内存 + pagefile)\n", WIDTH, 1.0 * (pi.CommitLimit - pi.CommitTotal) * pi.PageSize / GB);printf("\n");printf("%*.2f GB - 物理内存总量\n", WIDTH, 1.0 * pi.PhysicalTotal * pi.PageSize / GB);
printf("%*.2f GB - 已经使用的物理内存总量\n", WIDTH, 1.0 * (pi.PhysicalTotal - pi.PhysicalAvailable) * pi.PageSize / GB);
printf("%*.2f GB - 剩余物理内存总量\n", WIDTH, 1.0 * pi.PhysicalAvailable * pi.PageSize / GB);printf("\n");printf("%*d - 系统中当前句柄数\n", WIDTH, pi.HandleCount);
printf("%*d - 系统中当前进程数\n", WIDTH, pi.ProcessCount);
printf("%*d - 系统中当前线程数\n", WIDTH, pi.ThreadCount);

二、获取进程内存(物理内存、虚拟内存)

GetProcessMemoryInfo

  • PROCESS_MEMORY_COUNTERS
  • PROCESS_MEMORY_COUNTERS_EX
  • PROCESS_MEMORY_COUNTERS_EX2:Windows 10 22H2 with September 2023 cumulative update or Windows 11 22H2 with September 2023 cumulative update
PROCESS_MEMORY_COUNTERS_EX pmc;
pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS_EX);
if (GetProcessMemoryInfo(hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)))
{printf("%*d - 发生页错误次数\n", WIDTH, pmc.PageFaultCount);printf("%*.2f MB - 指定进程工作集内存峰值\n", WIDTH, pmc.PeakWorkingSetSize / MB);printf("%*.2f MB - 指定进程工作集内存\n", WIDTH, pmc.WorkingSetSize / MB);printf("\n");printf("%*.2f MB - 指定进程已经提交的私有内存总量(PagefileUsage)\n", WIDTH, pmc.PagefileUsage / MB);printf("%*.2f MB - 指定进程已经提交的私有内存总量峰值 PeakPagefileUsage\n", WIDTH, pmc.PeakPagefileUsage / MB);printf("%*.2f MB - 指定进程已经提交的私有内存总量(PrivateUsage)\n", WIDTH, pmc.PrivateUsage / MB);
}

QueryWorkingSet

  • PSAPI_WORKING_SET_INFORMATION

这个函数使用有点复杂,可以参考:

  • chrome base 库中 process_metrics_win.cc 文件中 GetWorkingSetKBytes 函数有完整的使用方法,但是发现最新版中已经没有此函数了
  • python - 获取与 Windows 中的任务管理器相同的进程详细信息
  • Getting same process details as task manager in Windows

GetProcessWorkingSetSize

Retrieves the minimum and maximum working set sizes of the specified process.
对于获取系统或进程内存没什么用

参考

  • Memory Performance Information
  • Process Memory Usage Information
  • PDC10: Mysteries of Windows Memory Management Revealed: Part Two
  • C++: Measuring memory usage from within the program, Windows and Linux
  • 第十四章 探索虚拟内存

相关文章:

  • Python编程技巧 – 装饰器
  • HCIA-HarmonyOS设备开发认证V2.0-IOT硬件子系统-GPIO
  • 深入理解java虚拟机---自动内存管理
  • 一.重新回炉Spring Framework: 理解Spring IoC
  • Python第十九章(模块)
  • PyCharm 新建目录 (directory or folder)
  • JavaScript 设计模式之组合模式
  • ubuntu 22.04 图文安装
  • Java使用Redis实现分页功能
  • 微服务中4种应对跨库Join的思路
  • 如何选择最适合的图纸加密软件?用户体验及性价比
  • 同一台宿主机上虚拟机CPU资源分配方式介绍
  • 【Redis实战】有MQ为啥不用?用Redis作消息队列!?Redis作消息队列使用方法及底层原理高级进阶
  • 剑指offer面试题16 反转链表
  • 【栈】150. 逆波兰表达式求值
  • Centos6.8 使用rpm安装mysql5.7
  • input的行数自动增减
  • Java IO学习笔记一
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • php ci框架整合银盛支付
  • Phpstorm怎样批量删除空行?
  • SegmentFault 技术周刊 Vol.27 - Git 学习宝典:程序员走江湖必备
  • 那些年我们用过的显示性能指标
  • 7行Python代码的人脸识别
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • 湖北分布式智能数据采集方法有哪些?
  • ​香农与信息论三大定律
  • #ubuntu# #git# repository git config --global --add safe.directory
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • (33)STM32——485实验笔记
  • (9)STL算法之逆转旋转
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (分享)自己整理的一些简单awk实用语句
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (十六)Flask之蓝图
  • (转)程序员技术练级攻略
  • (转载)Linux 多线程条件变量同步
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • .cfg\.dat\.mak(持续补充)
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET精简框架的“无法找到资源程序集”异常释疑
  • .net中的Queue和Stack
  • .xml 下拉列表_RecyclerView嵌套recyclerview实现二级下拉列表,包含自定义IOS对话框...
  • [Android]使用Git将项目提交到GitHub
  • [BZOJ4010]菜肴制作
  • [CSS] 点击事件触发的动画
  • [DAU-FI Net开源 | Dual Attention UNet+特征融合+Sobel和Canny等算子解决语义分割痛点]
  • [Docker]十.Docker Swarm讲解
  • [ffmpeg] 定制滤波器
  • [hdu 4405] Aeroplane chess [概率DP 期望]
  • [JavaWeb]—Spring入门
  • [LeetCode 127] - 单词梯(Word Ladder)
  • [leetcode] 四数之和 M
  • [LeetCode]—Anagrams 回文构词法