c# - 64 位 Windows 可以分配超过 7FFF'FFFF'FFFF 的虚拟内存吗?

标签 c# windows x86-64 virtual-memory internals

上下文

我正在努力升级 .NET 库以支持 64 位。该库直接在 Windows 上其他进程的内存中执行各种操作。我必须在 IntPtr(最大正值 7FFF'FFFF'FFFF'FFFF)或 UIntPtr(最大正值 FFFF'FFFF'FFFF'FFFF)两种类型之间进行选择处理我的内存指针。网上关于这两者的资料很多。 IntPtr 似乎是事实上 同意的选择,因为它符合 CLS 并且大多数 .NET API 都依赖它(引用 Marshal 来自InteropServices).

问题

我决定打开一个 64 位进程并检查分配的内存区域,以及进程中加载​​的模块,看看使用 UIntPtr 支持无符号指针是否有值(value)(地址> 7FFF'FFFF'FFFF'FFFF)。如下图所示,内存地址似乎没有加载符号,也没有分配超过 7FFF'FFFF'FFFF 的内存。这样做有具体原因吗?在某些情况下,Windows 可以在该值上分配内存区域吗?

Memory allocation on Cheat Engine (64-bit)

最佳答案

在Windows中每个进程只有8TB的地址空间,因此用户代码的上限是0x7FF'FFFF'FFFF

The range of virtual addresses that is available to a process is called the virtual address space for the process. Each user-mode process has its own private virtual address space. For a 32-bit process, the virtual address space is usually the 2-gigabyte range 0x00000000 through 0x7FFFFFFF. For a 64-bit process, the virtual address space is the 8-terabyte range 0x000'00000000 through 0x7FF'FFFFFFFF. A range of virtual addresses is sometimes called a range of virtual memory.

This diagram illustrates some of the key features of virtual address spaces.

some of the key features of virtual address spaces

https://learn.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/virtual-address-spaces

高248TB属于内核模式,总计256TB的地址空间,用48位寻址。这意味着最高可能的正地址是 247-1 = 0x7FFF'FFFF'FFFF

In 64-bit Windows, the theoretical amount of virtual address space is 2^64 bytes (16 exabytes), but only a small portion of the 16-exabyte range is actually used. The 8-terabyte range from 0x000'00000000 through 0x7FF'FFFFFFFF is used for user space, and portions of the 248-terabyte range from 0xFFFF0800'00000000 through 0xFFFFFFFF'FFFFFFFF are used for system space.


更新:

如下所述,在 Windows 8.1 和 Windows Server 2012 R2 或更高版本中,用户/内核地址空间拆分为 128/128TB,总计相同的 256TB 空间


重要部分是 48 位宽可能是因为大多数当前 x86-64 实现使用 48 位虚拟地址

The original implementation of the AMD64 architecture implemented 40-bit physical addresses and so could address up to 1 TB (240 bytes) of RAM. Current implementations of the AMD64 architecture (starting from AMD 10h microarchitecture) extend this to 48-bit physical addresses and therefore can address up to 256 TB of RAM. The architecture permits extending this to 52 bits in the future (limited by the page table entry format); this would allow addressing of up to 4 PB of RAM.

https://en.wikipedia.org/wiki/X86-64#Architectural_features

关于c# - 64 位 Windows 可以分配超过 7FFF'FFFF'FFFF 的虚拟内存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55358289/

相关文章:

vb.net - 使用命令行将 *.xls 或 *.xlsx 文件转换为管道分隔的 .csv 文件

x86-64 - 为什么 setjmp(3) 不保存 AMD64 上的所有寄存器?

c# - 数据类型 ntext 和 nvarchar 在等于运算符中不兼容

c# - 使用 Xpath expression.AddSort(...) 后无法使用 XmlDocument() 保存新的 xml 文件

c# BitConverter.GetBytes(float/double) 格式?

c# - 如何在 C# 中的 FontWeights 之间使用等于运算符?

windows - 如何在 PowerShell 中同时运行 2 个方法

windows - 将 Composer 安装的输出重定向到文本文件

assembly - 编译后的汇编代码产生不确定的结果

assembly - 使用 printf 在汇编 NASM 中打印数字