我想用:
打印变量的内存位置(地址)let x = 1;
println!("{:p}", &x);
这将打印十六进制值0x7fff51ef6380
,其十进制为140734568031104
。
我的电脑有16GB的RAM,为什么这么大的数字呢? x64架构是否使用大间隔序列而不是简单的1增量来访问内存位置?
在x86中,通常第一个位置从0开始,然后是1,2等,所以你可以拥有的最高数字大约为40亿,所以地址数总是等于或少于40亿。
为什么x64的情况不是这样?
答案 0 :(得分:11)
您在此处看到的是virtual memory的效果。内存管理很难,当操作系统和数百个进程必须共享内存时,内存管理变得更加困难。为了处理这种巨大的复杂性,使用了虚拟内存的概念。我只是简单地解释一下这里的基础知识;这个话题要复杂得多,你也应该把它读到别的地方。
在大多数现代计算机上,每个进程都认为它拥有(几乎)完整的内存空间。但是进程从不处理物理地址,而是处理虚拟地址。每次进程实际从内存中读取时,这些虚拟地址都会映射到物理地址。地址的这种转换由所谓的MMU(存储器管理单元)完成。如何映射地址的规则由操作系统设置。
启动PC时,操作系统会创建初始映射。每次启动进程时,操作系统都会向进程添加几片物理内存并相应地修改映射。这样一来,这个过程就有了记忆力。
在x86_64上,地址空间为64位宽,因此每个进程都认为它拥有所有这些2 ^ 64个地址。当然不是这样:
那么当你试图读取一个没有映射的地址时会发生什么(在64位的地址中,绝大多数是地址)? MMU触发页面错误。这使CPU通知操作系统处理此问题。
我的意思是在x86中,通常第一个位置从0开始,然后是1,2等,所以你可以拥有的最高数字大约是40亿。
确实如此,但如果x86系统的RAM少于4GB,也是如此。虚拟内存已存在很长时间了。
这就是为什么你会看到这么大的地址的简短摘要。请再次注意,我在这里隐藏了许多细节。
答案 1 :(得分:6)
您的程序使用的指针位于this.。 x86-64使用64位指针。这是AMD64的主要目标之一,同时添加了更多的整数和XMM寄存器。你是对的,i386只有32位指针,每个进程只能覆盖4GB的地址空间。
0x7fff51ef6380
看起来像一个堆栈指针,我觉得这个代码很有意义。
virtual address space:当前的x86-64硬件只实现48位虚拟地址,这是阻止软件依赖它的机制。这样可以在将来扩展地址空间而不会破坏软件。
系统中的物理RAM量 nothing 与此无关。你会在x86-64系统上看到(大约)相同的数字,内存为128MB,+ / - 堆栈Linux on x86-64 (for example) puts the stack near the top of the lower canonical address range。