C++;:从程序、Windows和Linux中测量内存使用情况 < >我想测量我的C++程序的内存使用情况。从程序内部,无分析器或进程查看器等
为什么要从程序内部执行?C++;:从程序、Windows和Linux中测量内存使用情况 < >我想测量我的C++程序的内存使用情况。从程序内部,无分析器或进程查看器等,c++,linux,winapi,memory-management,heap-memory,C++,Linux,Winapi,Memory Management,Heap Memory,为什么要从程序内部执行? 测量将进行数千次,必须自动化;因此,关注任务管理器,顶部,无论什么都不行 在生产运行期间进行测量-性能下降是不可接受的,这可能是由探查器引起的,因为运行时间已经不可忽略(对于大型问题实例,需要几个小时) 注意。为什么要进行测量?与提前计算“预期”使用量相比,测量已用内存(由操作系统报告)的唯一原因是,我无法直接分析“我的主要数据结构使用了多少?”。结构本身是 无序地图 它们被打包成一个向量(实际上,一个列表也就足够了,我只需要访问“相邻”结构;如果没有内存使用的详细信息
任务管理器
,顶部
,无论什么都不行无序地图
它们被打包成一个向量
(实际上,一个列表
也就足够了,我只需要访问“相邻”结构;如果没有内存使用的详细信息,我几乎无法决定选择哪一个)
vector
因此,如果有人知道如何“调整”这样一个结构所占用的内存的大小,这也会解决这个问题(尽管我可能不得不提出这个问题)
环境:可以假设程序在给定的机器上单独运行(当然还有操作系统等;PC或超级计算机的节点);它肯定是唯一一个需要大量(比如说>512 MiB)内存的计算实验环境的程序。该程序要么在我的家用电脑(16GiB RAM;Windows 7或Linux Mint 18.1)上运行,要么在机构超级计算机的节点(大约100GiB RAM,CentOS 7)上运行,程序可能希望消耗所有RAM请注意超级计算机有效地禁止用户进程的磁盘交换,而我的家用电脑的页面文件很小
内存使用模式。可以说该程序按顺序填充了一种表格,其中每一行都是上面指定的向量。假设基本数据结构称为supp
。然后,对于每个整数k
,要填充supp[k]
,需要supp[k-1]
中的数据。填充supp[k]
时,它用于初始化supp[k+1]
。因此,每次,此、上一个和下一个“表行”必须易于访问。填表后,程序在表中进行相对快速的(与“初始化”和填表相比)非穷举搜索,从而获得解决方案注意内存只通过STL
容器分配,我自己从来没有明确地new()
或malloc()
问题。一厢情愿。
从进程的源代码(一个用于Windows,一个用于Linux)内部测量进程的总内存使用量(包括交换到磁盘)的合适方法是什么
这可能是另一个问题,或者更确切地说是一个很好的谷歌搜索会话,但是——明确控制(比如鼓励或阻止)磁盘交换的正确(或简单)方法是什么?一本关于这一主题的权威书的指针是非常受欢迎的。再一次,请原谅我的无知,我想用“永不交换supp
”或
“交换支持[10]
”;然后,当我需要它时,“unswapsupp[10]
”—所有这些都来自程序的代码。我认为我必须解析序列化数据结构并将其显式存储为二进制文件,然后反转转换
在Linux上,通过sbrk(0)捕获堆指针,将它们转换为64位无符号整数,并在分配内存后计算差异似乎是最简单的方法,这种方法产生了合理的结果(还没有进行更严格的测试)
编辑5。删除了对HeapAlloc
争论无关的引用
编辑4。Windows解决方案
此代码位报告与Task Manager中的工作集匹配的工作集;这就是我想要在Windows 10 x64上测试的全部内容(通过new-uint8\u t[1024*1024]
或更确切地说,new-uint8\u t[1all等分配进行测试,以了解查询进程工作集或更可能的私有工作集需要多少物理内存。工作集是(或多或少)进程在RAM中使用的物理页数。专用工作集不包括共享内存
看
有关术语和更多详细信息
这两个指标都有性能计数器
(您也可以使用queryworkset(Ex)
自己计算,但我认为这太糟糕了。您可以使用GetProcessMemoryInfo
获得(非私有)工作集)
但更有趣的问题是,这是否有助于你的程序做出有用的决定。如果没有人要求内存或使用它,那么仅仅是你正在使用大部分物理内存这一事实就没有什么意义。或者你担心你的程序单独使用太多内存吗
您没有提到它使用的算法或内存使用模式。如果它使用大量内存,但主要是按顺序使用,并且很少返回到旧内存,则可能不是问题。Windows写“旧”为了满足对物理内存的需求,在分页出驻留页之前,迫切需要将页转到磁盘
#include<Windows.h>
#include<Psapi.h>
//get the handle to this process
auto myHandle = GetCurrentProcess();
//to fill in the process' memory usage details
PROCESS_MEMORY_COUNTERS pmc;
//return the usage (bytes), if I may
if (GetProcessMemoryInfo(myHandle, &pmc, sizeof(pmc)))
return(pmc.WorkingSetSize);
else
return 0;