内存管理:虚拟地址空间以及编译模式

Posted xiaobaizzz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存管理:虚拟地址空间以及编译模式相关的知识,希望对你有一定的参考价值。

虚拟地址空间:就是程序可以使用的虚拟地址的有效范围。虚拟地址空间的大小由操作系统决定,但还会受到编译模式的影响。

  • CPU的数据处理能力
    • 地址总线:用于在内存上定位数据,例如:地址总线有20根,寻址能力为2^20 = 1MB
    • 数据总线:位于主板之上,不在CPU中,用于在CPU和内存之间传输数据。决定了CPU单次的数据处理能力。(64位 = 寄存器的位数 = 数据总线的宽度)
    • 主频:决定了CPU单位时间内的数据处理次数。(4GHz)
    • 数据总线 × 主频 = CPU单位时间内的数据处理量。
  • 实际支持的物理内存
    • CPU支持的物理内存只是理论上的数据,实际应用中还会受到操作系统的限制。
  • 编译模式
    • 为了兼容不同的平台,现代编译器都支持两种编译模式:32位模式和64位模式
    • 32位编译模式:
      • 一个指针或地址占用4个字节的内存,共32位。理论上能够访问的虚拟内存空间大小为2^32 = 4GB,有效虚拟地址范围是0 - 0XFFFFFFFF。
      • 换句话说,程序能够使用的最大内存为4GB,跟物理内存没有关系。
      • 如果程序需要的内存大于物理内存,或者内存中剩余的空间不足,操作系统会将内存中暂时用不到的数据写入磁盘,等需要的时候再读取回来。
      • 如果物理内存大于4GB,程序也只能使用4GB
    • 64位编译模式:
      • 一个指针或地址占用8个字节的内存,共64位。理论上能够访问的虚拟内存空间大小为2^64。
      • 因为2^64的虚拟内存空间太大了,Windows和Linux都对虚拟地址进行了限制,仅使用虚拟地址的低48位(6个字节), 2^48 = 256TB
    • 注意:
      • 64位的CPU运行64位的程序才能发挥它的最大性能,运行32位的程序会白白浪费一部分资源。
      #include<iostream>
      using namespace std;
      
      int a;
      int main(){
          int *p = &a;
          cout << "p = " << p << " -> " << sizeof(int*) << "位" << endl;
          return 0;
      }
      /*运行结果*/
      p = 0x491020 -> 4位 //32位编译模式
      p = 0x4a7030 -> 8位 //64位编译模式

以上是关于内存管理:虚拟地址空间以及编译模式的主要内容,如果未能解决你的问题,请参考以下文章

Linux 操作系统原理 — 内存管理 — 虚拟地址空间(x86 32bit 系统)

Linux 操作系统原理 — 内存管理 — 虚拟地址空间(x86 32bit 系统)

物理内存虚拟内存bufferscached共享内存swap

Linux 内核 内存管理虚拟地址空间布局架构 ② ( 用户虚拟地址空间组成 | 内存描述符 mm_struct 结构体源码 )

深入理解java虚拟机---java虚拟机内存管理

Linux虚拟地址空间布局以及进程栈和线程栈总结(转)