内存限制【从硬件到进程】
本文目录 15 个章节
内存限制【从硬件到进程】
# 内存限制【从硬件到进程】
创建时间:2021/6/27 23:40
- 问题的提出
- 基础知识
- 存储单元
- 存储单元与机器字
- 内存限制
- CPU的内存限制
- 操作系统的内存限制
- 物理内存限制
- 32位系统
- 64位系统
- 如何确认
- 虚拟地址空间
- 用户空间和系统空间
- 虚拟地址空间限制
- 物理内存限制
- Ref
- 基础知识
问题的提出
应用程序的内存受进程的虚拟地址空间限制。32位进程最多能分配1.5GB,64位进程最多能分配8TB。
基础知识
存储单元
存储单元 : 多个存储元的集合,一般应具有存储数据和读写数据的功能,以8个二进制位(bit)作为一个存储单元,也就是一个字节(Byte)。
每个单元有一个地址,是一个整数编码,可以表示为二进制整数。程序中的变量和主存储器的存储单元相对应。变量的名字对应着存储单元的地址,变量内容对应着单元所存储的数据。
存储单元与机器字
存放一个机器字的存储单元,通常称为字存储单元,相应的单元地址叫字地址。而存放一个字节的单元,称为字节存储单元,相应的地址称为字节地址。如果计算机中可以编址的最小单元是字存储单元,则该计算机称为按字寻址的计算机。如果计算机中可编址的最小单位是字节,则该计算机称为按字节寻址的计算机。如果机器字长等于存储器单元的位数,一个机器字可以包含数个字节,所以一个存储单元也可以包含数个能够单独编址的字节地址。例如一个16位二进制的字存储单元可存放两个字节,可以按字地址寻址,也可以按字节地址寻址。当用字节地址寻址时,16位的存储单元占两个字节地址。
内存限制
- CPU可访问的内存,受寻址范围的限制,即受到地址线数量(即地址位数)的限制。
- 操作系统能使用的内存受CPU、主板等的硬件的限制,以及操作系统本身的限制。
- 应用程序的内存受进程的虚拟地址空间限制,即受到操作系统的限制。
CPU的内存限制
地址总线的数目决定了CPU的寻址范围,这种由地址总线对应的地址称为 物理地址
32位的CPU:一般情况下32位的CPU的地址总线是32位,提供的可寻址物理地址范围 为 2^32=4GB。(所以在32位CPU和32位的操作系统中,理论上最大支持的内存为4G,实际上只有3.2G左右)
也有部分32位的CPU地址总线是36位的,比如用做服务器的CPU。
64位CPU:64位系统使用64位地址线的最大寻址空间为2的64次方bytes,计算后其可寻址空间达到了18446744073709551616 Bytes,即16384PB(PebiByte)或16777216TB(TebiByte)。但是,很多64位CPU使用36或40位地址线,最大寻址空间仅为64GB或1TB。
例如:据2015年5月的状况,Intel的32位架构下,可使用的地址线是36个,可使用的最大物理地址是2^36B,折合64GB,可用的地址空间是4GB。64位架构下,地址线是46个,所以最大的物理地址是2^46B,折合64TB,可用地址空间也是这么大。
操作系统的内存限制
物理内存限制
32位系统
虽然32位环境下实际上CPU支持访问大于4G的物理内存,但Windows将此功能屏蔽了,导致了32位Windows实际只能使用4G的物理地址空间。
虽然物理地址有4G,我们还是不能完全使用它,像显卡也需要占用一部分内存。CPU要访问显卡上的显存,就必须把物理地址空间的一部分用于标识显存,这样可以让CPU操作显存像操作内存一样,这种技术被称为memory-mapped I/O。而这部分内存通常是直接划归显卡使用,不会显示在系统中,因此,可用的内存就少于4G了。
在Windows的设备管理器里,查看显卡的属性页里的“资源”,可以看到内存映射的地址范围,实际上不管32位还是64位,都需要占用一部分地址空间。 实际上不仅仅是显存,你电脑上的PCI控制器,各种网卡、声卡、USB控制器等等都需要占用一定的物理内存,所以最终的后果就是可用的物理地址范围变得特别少,最少可能只有1.99GB,这种限制在32位Windows上是不可改变的。
64位系统
64位系统根据不同版本的限制,对支持的物理内存大小有不同的限制。如下文所示: https://docs.microsoft.com/en-us/windows/win32/memory/memory-limits-for-windows-releases
如何确认
要确认自己的电脑能支持多大内存,首先需要确认系统版本,然后还要确认主板和CPU所支持的容量,确认这三个后才能确定最终实际能够支持的最大容量是多少。 CMD确认方法:
public class AGenericClass<T> where T : IComparable<T> { }
虚拟地址空间
当处理器读取或写入内存位置时,它会使用虚拟地址。 在读取或写入操作过程中,处理器会将虚拟地址转换为物理地址。
用户空间和系统空间
诸如 Notepad.exe 和 MyApp.exe 的进程在用户模式下运行。 核心操作系统组件和多个驱动程序在更有特权的内核模式下运行。 详见:https://docs.microsoft.com/zh-cn/windows-hardware/drivers/gettingstarted/user-mode-and-kernel-mode
- 每个用户模式进程都有其各自的专用虚拟地址空间,但在内核模式下运行的所有代码都共享称为“系统空间” 的单个虚拟地址空间。 用户模式进程的虚拟地址空间称为“用户空间” 。
- 用户模式下运行的代码可以访问用户空间,但不能访问系统空间。 此限制可防止用户模式代码读取或更改受保护的操作系统数据结构。 内核模式下运行的代码既可以访问用户空间,也可以访问系统空间。 即,内核模式下运行的代码可以访问系统空间和当前用户模式进程的虚拟地址空间。
虚拟地址空间限制
虚拟地址空间取决于虚拟地址的位数。
如64位linux一般使用48位来表示虚拟地址空间,使用40位来表示物理地址空间,可以通过cat /proc/cpuinfo来查看
48位地址可以寻址的范围是256TB。虚拟地址空间一部分用于用户模式,一部分用于内核模式(一般为各分一半)。
如在 32 位 Windows 中,可用的虚拟地址空间共计为 2^32 字节(4 GB)。 通常,较低的 2 GB 用于用户空间,较高的 2 GB 用于系统空间。
以下链接中包含不同操作系统的 Memory and Address Space Limits。 https://docs.microsoft.com/en-us/windows/win32/memory/memory-limits-for-windows-releases
可见,一些64位系统中,由于虚拟地址位数位48,虚拟地址空间大小为256TB,而用户模式可用的虚拟地址空间为128TB。

由下图可见,较早的64位Windows系统支持的User-mode 虚拟地址空间大小位8TB。文章中提到.NET进程最多能分配8TB可能与此有关。

Ref
https://baike.baidu.com/item/%E5%AD%98%E5%82%A8%E5%8D%95%E4%BD%8D
32位系统只能寻址4G空间,64位则是128G,这些是怎么算出来的?:https://www.zhihu.com/question/29962475
为何微软不在新的操作系统中让 32 位支持大于 4GB 的内存?:https://www.zhihu.com/question/22594254/answer/42967413 https://docs.microsoft.com/en-us/windows/win32/memory/memory-limits-for-windows-releases