改进Windows应用程序中的堆内存使用情况报告

时间:2015-10-07 17:05:23

标签: c windows memory memory-management

在使用下面的代码时,我发现内存使用量的增加在 PROCESS_MEMORY_COUNTERS 的变量成员中相当快地注册,但是因为内存是在继续运行的进程中释放,似乎减少内存使用似乎没有注册

time_t GetMemUsage(void)
{
    HANDLE hProcess;
    PROCESS_MEMORY_COUNTERS pmc;
    DWORD processID = GetCurrentProcessId();

    hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION |
                                    PROCESS_VM_READ,
                                    FALSE, processID );
    GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc));
    CloseHandle(hProcess);

    return pmc.PeakWorkingSetSize;
}

使用任务管理器,我可以在终止进程后几乎立即看到物理内存大小发生变化(更小),但是在调用上述函数之前,即使经过一段时间的延迟,进程也会释放内存,没有注册。

我不确定我的观察结果是由于free()的工作方式。 (也就是说,它可能不会通知操作系统内存被释放),或者Windows只是在将它注册到PROCESS_MEMORY_COUNTERS结构中的速度很慢。

在任何情况下,是否有人了解更好的技术,以便在正在运行的流程中获得更及时和准确的实际内存使用情况报告?

我也尝试过查看pmc.WorkingSetSizepmc.PagefileUsage相同的结果。

1 个答案:

答案 0 :(得分:1)

这里有几件事情。

  1. 内存管理员在释放后往往会保留内存。理论上说,你可能很快就需要更多的内存,而且你最近使用的内存比从操作系统获取更多内存要便宜。因此,从操作系统的角度来看,您的程序仍在使用已释放的内存。

  2. 工作集大小是对程序使用的内存的间接度量。操作系统根据程序的内存需求,根据系统上运行的所有其他内存压力确定工作集大小。当您的程序开始使用更多内存时,操作系统将(通常)快速增加进程的工作集以适应它。如果您的程序将一堆内存释放回操作系统,这并不一定意味着操作系统将调整进程的工作集大小。事实上,如果有足够的RAM可用,它可能不会打扰。但是,如果许多其他进程需要内存,并且您开始达到RAM的容量,那么操作系统将开始修剪那些目前需要的工作集。

  3. 您的代码示例似乎是报告峰值工作集大小而不是当前工作集大小。峰值告诉您进程在其生命周期内达到的最大工作集大小,即使当前工作集小得多。