代码之家  ›  专栏  ›  技术社区  ›  Suma

单个虚拟分配使用的内存(和其他资源)

  •  4
  • Suma  · 技术社区  · 14 年前

    VirtualAlloc (xxxx, yyy, MEM_RESERVE, zzz) ?

    VirtualAlloc( xxxx, 1024*1024, MEM_RESERVE, PAGE_READWRITE )
    

    或者多个更小的块,比如:

    VirtualAlloc( xxxx, 64*1024, MEM_RESERVE, PAGE_READWRITE );
    VirtualAlloc( xxxx+1*64*1024, 64*1024, MEM_RESERVE, PAGE_READWRITE );
    VirtualAlloc( xxxx+2*64*1024, 64*1024, MEM_RESERVE, PAGE_READWRITE );
    ...
    VirtualAlloc( xxxx+15*64*1024, 64*1024, MEM_RESERVE, PAGE_READWRITE );
    

    如果有人不知道答案,但可以建议一个实验,将能够检查它,这将是有益的。

    其动机是我想实现将内存返回到操作系统,以便 TCMalloc

    4 回复  |  直到 14 年前
        1
  •  3
  •   Jeff Wilhite    14 年前

    仅供参考,您可以使用GetProcessMemoryInfo和GlobalMemoryStatusEx来获取一些内存使用度量。

    void DisplayMemoryUsageInformation()
    {
        HANDLE hProcess = GetCurrentProcess();
        PROCESS_MEMORY_COUNTERS pmc;
        ZeroMemory(&pmc,sizeof(pmc));
        GetProcessMemoryInfo(hProcess,&pmc, sizeof(pmc));
        std::cout << "PageFaultCount:             " << pmc.PageFaultCount             << std::endl;
        std::cout << "PeakWorkingSetSize:         " << pmc.PeakWorkingSetSize         << std::endl;
        std::cout << "WorkingSetSize:             " << pmc.WorkingSetSize             << std::endl;
        std::cout << "QuotaPeakPagedPoolUsage:    " << pmc.QuotaPeakPagedPoolUsage    << std::endl;
        std::cout << "QuotaPagedPoolUsage:        " << pmc.QuotaPagedPoolUsage        << std::endl;
        std::cout << "QuotaPeakNonPagedPoolUsage: " << pmc.QuotaPeakNonPagedPoolUsage << std::endl;
        std::cout << "QuotaNonPagedPoolUsage:     " << pmc.QuotaNonPagedPoolUsage     << std::endl;
        std::cout << "PagefileUsage:              " << pmc.PagefileUsage              << std::endl;
        std::cout << "PeakPagefileUsage:          " << pmc.PeakPagefileUsage          << std::endl;
    
        MEMORYSTATUSEX msx;
        ZeroMemory(&msx,sizeof(msx));
        msx.dwLength = sizeof(msx);
        GlobalMemoryStatusEx(&msx);
        std::cout << "MemoryLoad:                 " << msx.dwMemoryLoad               << std::endl;
        std::cout << "TotalPhys:                  " << msx.ullTotalPhys               << std::endl;
        std::cout << "AvailPhys:                  " << msx.ullAvailPhys               << std::endl;
        std::cout << "TotalPageFile:              " << msx.ullTotalPageFile           << std::endl;
        std::cout << "AvailPageFile:              " << msx.ullAvailPageFile           << std::endl;
        std::cout << "TotalVirtual:               " << msx.ullTotalVirtual            << std::endl;
        std::cout << "AvailVirtual:               " << msx.ullAvailVirtual            << std::endl;
        std::cout << "AvailExtendedVirtual:       " << msx.ullAvailExtendedVirtual    << std::endl;
    }
    
        2
  •  2
  •   Mike    14 年前

    通过使用reserve参数进行VirtualAlloc调用,可以使用零(实际上是零)内存。这只会在进程中保留地址空间。在使用VirtualAlloc和commit参数实际返回带有页的地址之前,不会使用内存。 这本质上就是虚拟字节(占用的地址空间量)和私有字节(提交的内存量)之间的区别。 您对VirtualAlloc()的两种使用都将保留相同的内存量,因此从资源消耗的角度来看,它们是等效的。 his blog . 他写了几篇文章叫做《突破极限》,其中包括了其中的一些内容。如果你想了解真正的细节,那么你应该读他的书( Microsoft Windows Internals ). 这是迄今为止我读过的关于windows如何管理内存(以及其他一切)的最好的参考资料。

    (编辑)附加信息: 将virtual alloc与reserve参数一起使用时,将创建页目录条目(32位),并创建页表条目(32位)。此时,不会为保留内存创建页。 查看此信息的最佳方法是使用内核调试器。我建议使用LiveKD(sysinternals)。您可以使用liveKD而无需连接远程计算机,但它不允许实时调试。加载LiveKD,并选择您的进程。那你就可以跑了!PTE命令检查进程的页表。

    同样,我建议你阅读Windows内部的内容。在我的版本(第四版)中,有一章(超过100页)介绍了所有这些内容,并举例说明了如何遍历liveKD中的各种数据结构。

        3
  •  0
  •   peterchen    14 年前

    不过:使用VirtualFree你可以有选择地 退役 单个页面或页面范围。对于已取消提交的页,虚拟地址范围(在进程内)仍保留,但没有为其分配物理内存(RAM或交换文件)。稍后可以使用VirtualAlloc再次提交这些页面。

    因此,除非需要为进程中的其他分配器释放地址空间,否则可以使用此机制有选择地请求内存并将内存返回给操作系统。

    [编辑]

    测量

    地址空间碎片警告 -小心你的返回算法。当以“谁是自由的”方式将各个页面返回到进程时,您可能会得到一个碎片地址空间,该空间有80%的可用内存,但没有100K的可用内存。

        4
  •  0
  •   Chubsdad    14 年前

    您可以尝试使用“perfmon”并添加计数器(例如内存)来开始了解VirtualAlloc正在使用哪些资源。您必须在调用VirtualAlloc之前和之后拍摄快照

    http://windbg.info/doc/1-common-cmds.html#20_memory_heap 想知道到底发生了什么。