关于 windows 下获取程序内存

本文非常不严谨,但是 OIer 日常(考场)使用应该是没有问题的吧。

获取程序 Process ID

程序内调用 getpid() 即可。

例如:

#include<bits/stdc++.h>
using namespace std;

int main() {
    cout << getpid() << '\n';
    return 0;
}

注意每次重新调用程序,程序的 pid 都会改变pid 是 Process ID 的缩写)。

查看程序占用内存

  • 在线查看,即查看程序当前使用的内存。
  • 启动程序,注意不要让程序停止(可以用 Sleep 函数,或者直接写上 while(1);)。
  • 打开 cmd,写上 wmic process where processid=PID get WorkingSetSize,其中 PID 替换成你要检测的程序的 pid。
  • 接下来 cmd 会给出当前程序占用的内存大小,单位是 B。
  • 注意该方法无法检测在程序中已经被 delete 或其它方法释放的内存
  • 另外一个比较高级,可以查看的东西更加丰富,但是:
    需要#include<windows.h>#include<psapi.h>,并且在编译选项里面加上 -lPsapi -DPSAPI_VERSION=1
  • 接下来所有操作均在你的程序内完成。
  • 首先需要获取程序的 pid,记为 processID,然后写上如下片段(我也不知道有什么用,但是背住就好了):
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;

hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);

if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
    /*...*/
}

代码中注释掉的部分换成你想查询的内容,具体来说,有:

  • cbSize of the structure, in bytes.
    PageFaultCountNumber of page faults. // 缺页中断次数
    PeakWorkingSetSizePeak working set size, in bytes. // 使用内存高峰
    WorkingSetSizeCurrent working set size, in bytes. // 当前使用的内存
    QuotaPeakPagedPoolUsagePeak paged pool usage, in bytes. // 使用页面缓存池高峰
    QuotaPagedPoolUsageCurrent paged pool usage, in bytes.// 使用页面缓存池
    QuotaPeakNonPagedPoolUsagePeak nonpaged pool usage, in bytes.// 使用非分页缓存池高峰
    QuotaNonPagedPoolUsageCurrent nonpaged pool usage, in bytes.// 使用非分页缓存池
    PagefileUsageCurrent space allocated for the pagefile, in bytes.Those pages may or may not be in memory.// 使用分页文件
    PeakPagefileUsagePeak space allocated for the pagefile, in bytes.// 使用分页文件高峰

    (分页文件大概就是虚拟内存)
  • 一般来说,查看自己程序使用的内存需要使用 PeakPagefileUsage,而不是 PeakWorkingSetSize,因为程序完全可能因为内存不足使用分页文件。
  • 示例程序:
#include <bits/stdc++.h>
#include <windows.h>
#include <psapi.h>

void PrintMemoryInfo(DWORD processID) {
    std::cout << "\nProcess ID: " << processID << '\n';

    HANDLE hProcess;
    PROCESS_MEMORY_COUNTERS pmc;

    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
    if (hProcess == nullptr) {
        std::cerr << "hProcess = nullptr!!!\n";
        return;
    }

    if (!GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
        std::cerr << "GetProcessMemoryInfo Failed\n";
        return;
    }
    std::cout << "\tPeakPagefileUsage: " << pmc.PeakPagefileUsage << "Byte\n";

    CloseHandle(hProcess);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    // You can leave out the above two sentences.
    /*
        codes here
    */ 
    PrintMemoryInfo(getpid());
    return 0;
}

最后,提醒一下,貌似加了这些东西之后,会发生一些奇怪的编译错误,作者不太懂,反正如果你发生了奇怪的错误就把这些删掉再试试。