【发布时间】:2017-06-09 09:16:50
【问题描述】:
看,我想测量我的 C++ 程序的内存使用情况。从程序内部,无需分析器或进程查看器等。
为什么是在程序内部?
- 测量将进行数千次——必须自动化;因此,关注
Task Manager、top,无论如何,都行不通 - 在生产运行期间进行测量—性能下降(可能由分析器引起)是不可接受的,因为运行时间已经不可忽略(对于大型问题实例需要几个小时)
注意。为什么要测量? 测量已用内存(由操作系统报告)而不是提前计算“预期”使用量的唯一原因是我不能直接分析“sizeof”多少我的主要数据结构是否使用。结构本身是
unordered_map<bitset, map<uint16_t, int64_t> >
这些都被打包到 vector 中(list 实际上也足够了,我只需要访问“相邻”结构;没有有关内存使用的详细信息,我几乎无法决定哪个选择)
vector< unordered_map<bitset, map<uint16_t, int64_t> > >
因此,如果有人知道如何“调整”这种结构占用的内存,那也可以解决问题(尽管我可能不得不提出问题或其他问题)。
环境: 可以假设程序在给定的机器上单独运行(当然还有操作系统等;PC 或超级计算机的节点);它肯定是唯一需要大量(例如 > 512 MiB)内存的程序——计算实验环境。该程序可以在我的家用 PC(16GiB RAM;Windows 7 或 Linux Mint 18.1)或机构超级计算机的节点(大约 100GiB RAM,CentOS 7)上运行,并且该程序可能希望消耗所有这些内存。 注意,超级计算机有效地禁止了用户进程的磁盘交换,而我的家用 PC 有一个较小的页面文件。
内存使用模式。该程序可以说是按顺序填充一个表格,其中每一行是上面指定的vector<...>。假设主要数据结构称为supp。然后,对于每个整数k,填充supp[k],需要来自supp[k-1] 的数据。当supp[k] 被填充时,它用于初始化 supp[k+1]。因此,每一次,this、prev 和 next“表格行”都必须易于访问。填表后,程序在表中进行相对快速的(与“初始化”和填表相比)、非穷举搜索,通过该搜索获得解决方案。 注意内存只通过STL容器分配,我自己从来没有明确new()或malloc()。
问题。一厢情愿。
- 从源代码内部测量进程的总内存使用(包括交换到磁盘)的适当方法是什么(一种用于 Windows,一种用于 Linux) ?
- 应该是另一个问题,或者更确切地说是一个很好的谷歌搜索,但仍然---明确控制(比如鼓励或阻止)交换到磁盘的正确(或简单)方法是什么?非常欢迎指向有关该主题的权威书籍。再次,原谅我的无知,我想在“永远不要交换
supp”或 “交换supp[10]”;然后,当我需要它时,“取消交换supp[10]”——全部来自程序代码。我想我必须解决序列化数据结构并将它们显式存储为二进制文件,然后反转转换。
在 Linux 上,通过 sbrk(0) 捕获堆指针,将它们转换为 64 位无符号整数,并在分配内存后计算差异,这种方法产生了合理的结果(没有做更严格的测试)。
edit 5. 删除了对HeapAlloc wrangling 的引用——无关紧要。
编辑 4. Windows 解决方案
这段代码报告了与任务管理器中的工作集匹配的工作集;这就是我想要的一切——在 Windows 10 x64 上进行了测试(通过 new uint8_t[1024*1024] 之类的分配进行测试,或者更确切地说,new uint8_t[1ULL << howMuch],尚未在我的“生产”中进行测试)。
在 Linux 上,我会尝试 getrusage 或其他类似的东西。
正如@IInspectable 和@conio 所建议的,主要元素是GetProcessMemoryInfo
#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;
edit 5. 删除了对GetProcessWorkingSetSize 的不相关引用。谢谢@conio。
【问题讨论】:
-
虚拟内存相当复杂。您希望衡量什么特定的统计数据?
-
我想要最接近 RAM 使用率的值,正如任务管理器“为单个进程保留的总物理内存”或顶部所报告的那样。我不打算爬进虚拟内存,应该报告RAM的使用情况。
-
对于 Windows,请查看 Process Memory Usage Information。此外,您的程序不消耗 RAM。它消耗地址空间。 RAM 只是一种性能优化。
-
如果你假装虚拟内存的复杂性不存在,那么我怀疑你会得到很大的帮助。你将如何处理这些信息。它将通知哪些决定?
-
内存使用决定了给定的问题实例是否可以解决(实际的相关统计数据是每个状态的平均内存使用量,通过将内存使用量除以状态数获得)。它还可能影响程序内部结构的选择(我无法“分析地”计算
std::unordered_map<...>的内存使用量,所以我决定去经验。
标签: c++ linux winapi memory-management heap-memory