“私人字节”没有反映出来。如何找到进程分配的确切内存?

Posted

技术标签:

【中文标题】“私人字节”没有反映出来。如何找到进程分配的确切内存?【英文标题】:"Private Bytes" doesn't reflect it. How to find exact memory allocated by process? 【发布时间】:2014-08-15 16:04:33 【问题描述】:

这是在 Windows XP 上使用 VS2010 编译和运行的 C++ 代码示例。

它在分配前后打印“私有字节”。

void PrintPrivateBytes()

    HANDLE current_process;
    PROCESS_MEMORY_COUNTERS_EX pmc;

    current_process = GetCurrentProcess();

    if (!GetProcessMemoryInfo(current_process, (PPROCESS_MEMORY_COUNTERS)&pmc, sizeof(pmc)))
    
        std::cout << "\nGetProcessMemoryInfo failed" ;
        return;
    

    std::cout << "\nProcess private bytes: " << pmc.PrivateUsage/1024 << " KB"; 


int _tmain(int argc, _TCHAR* argv[])

    // Code demonstrating private bytes doesn't change
    std::cout << "\n\nBefore allocating memory" ;
    PrintPrivateBytes();

    char* charptr = new char[8192];
    std::cout << "\n\nAfter allocating 8 KB memory" ;
    PrintPrivateBytes();

    delete[] charptr;
    std::cout << "\n\nAfter deleting memory" ;
    PrintPrivateBytes();

    int RetVal = _heapmin();
    std::cout << "\n\nAfter calling _heapmin" ;
    PrintPrivateBytes();

    return 0;

这是输出:

分配内存之前

处理私有字节:416 KB

分配内存后

处理私有字节:428 KB

删除内存后

处理私有字节:428 KB

调用_heapmin后

处理私有字节:428 KB

它表示“私有字节”不反映进程的确切内存使用情况。

哪种 Windows API/结构将有助于找到进程的准确内存使用情况? (工作集也没什么用。它只是反映了物理内存的使用情况)

【问题讨论】:

_heapmin的返回值是多少? @Werner: 它返回 0 您不应该期望进程中释放的内存会立即返回给操作系统。您看到的行为是正常的。 假设您谈论的是已提交内存的总量,您可以使用VirtualQuery 来解决这个问题。另请注意,Visual Studio C 运行时的源代码是可用的,因此您可以查看 _heapmin 的具体实现方式。 【参考方案1】:

您检查私有字节的解决方案是正确的,只是您对 _heapmin 的假设是错误的。

_heapmin 不像记录的那样工作。 _heapmin 为 documented,表示“将未使用的堆内存释放给操作系统。”

实现(参见“\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src\heapmin.c”)是

int __cdecl _heapmin(void)

        if ( HeapCompact( _crtheap, 0 ) == 0 ) 
            return -1;
        
        else 
            return 0;
        

HeapCompact 是documented,尽管返回堆中最大空闲块的大小,但通常什么都不做。如果使用特殊的全局(调试目的)标志,它只会做一些额外的事情。

【讨论】:

我明白了。但问题是如何找到进程获取的确切内存?如果没有办法,就很难说进程有没有内存泄漏。 @Andrew 我的意思是:您读取私有字节的解决方案不一定是错误的,因为您所做的观察。 @Andrew _heapwalk 等。人。请注意,这不是您的问题;运行时是进程的一部分,因此它的堆是“进程获取的内存”,即使它不是“我的代码获取的内存”。

以上是关于“私人字节”没有反映出来。如何找到进程分配的确切内存?的主要内容,如果未能解决你的问题,请参考以下文章

它在Javascript中的确切含义(分配变量)[重复]

如何把 .NET 进程中的所有托管异常找出来?

[转]深入C语言内存区域分配(进程的各个段)详解

如何找到矩阵中最小值的确切数量? [复制]

堆是如何在进程之间分配的?

如果已知 void* 分配大小,如何将确切的内存大小传递给 free()