【问题标题】:Question on querying memory regions (Windows)关于查询内存区域的问题(Windows)
【发布时间】:2020-08-17 11:24:07
【问题描述】:

我编写了一个程序,它使用以下属性枚举进程的所有内存区域:MEM_COMMIT 和 PAGE_READWRITE,并且在程序结束时打印找到的所有区域的总大小,一切似乎都运行良好,然后我在 64 位程序上尝试了它,结果发现总区域大小大于我 PC 上可用的 RAM。 在我的 PC 上,有 15.9GB 的 RAM 可用,而我进行的扫描之一是 18.363.846.656 字节(18.3 GB)。 我想知道,这怎么可能?这是我的代码中的错误,还是他们使用了一些我不知道的内存管理方法?

#include <iostream>
#include <Windows.h>

int main()
{
   // Get an handle to the process
   HWND hWnd = FindWindowA(NULL, "WindowName");
   DWORD pid; GetWindowThreadProcessId(hWnd, &pid);
   HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);

   // Declaration of some variables
   char* Ptr(0);
   MEMORY_BASIC_INFORMATION Mem;
   size_t totalSize = 0;

   // Start querying
   while (VirtualQueryEx(hProcess, Ptr, &Mem, sizeof(MEMORY_BASIC_INFORMATION)))
   {
      if (Mem.State == MEM_COMMIT && Mem.Protect == PAGE_READWRITE)
      {
         totalSize += Mem.RegionSize;
         std::cout << std::hex << Mem.BaseAddress << " - " << (LPVOID)(Mem.RegionSize + (INT64)Mem.BaseAddress) << " - size:(" << std::dec << Mem.RegionSize << ")\n";
      }

      Ptr += Mem.RegionSize;
   }

   std::cout << "[" << totalSize << "]";
   CloseHandle(hProcess);
   return 0;
}

【问题讨论】:

  • 你走的是虚拟内存,不是物理内存。虚拟内存区域可以在任何给定时间交换到磁盘,并且不受物理内存的支持。
  • 谢谢,但我想知道如何只考虑物理内存?在 MEMORY_BASIC_INFORMATION 结构中,我看不到任何值可以帮助我了解它是否在物理内存中

标签: c++ memory memory-management


【解决方案1】:

您无法使用任何正常记录的 Windows API 函数查询物理内存。虚拟内存旨在成为一种抽象,操作系统旨在为您在后台处理所有这些。

SysInternals 的RAMMap 可以显示有关物理内存的信息,但源代码不公开。 RAMMap 在 Microsoft 的 video 中进行了解释

要了解有关系统工作原理的更多信息,您可以在 Windows Internals 书中查找“物理内存”。

这个答案中有一些代码声称能够使用 NtOpenSection 和 NtMapViewOfSection 从用户模式 ​​here 查询物理内存。

要与内核驱动程序中的物理内存交互,您可以阅读this source code

【讨论】:

    猜你喜欢
    • 2019-08-01
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 2019-09-19
    • 2011-10-08
    • 2016-03-14
    相关资源
    最近更新 更多