编程环境中的虚拟地址空间

我对虚拟地址空间的含义感到困惑。 在32位机器中,进程可以处理2 ^ 32个存储器位置。 这是否意味着每个进程的虚拟地址空间是2 ^ 32(4GB)?

以下是进程的虚拟地址空间的快照。 这可以增长到4GB吗? 这种系统中的进程数量是否有限制?

在此处输入图像描述

这可以增长到4GB吗?

地址空间的大小由唯一指针值的数量限制。 对于32位处理器,32位值可以表示2 ^ 32个不同的值。 如果允许每个这样的值来寻址不同的内存字节,则会得到2 ^ 32个字节,相当于4千兆字节。

所以,是的,一个进程的虚拟地址空间理论上可以增长到4 GB。 但实际上,这也可能取决于系统和处理器。 可以看出:

然而,在Pentium类处理器上无法实现这种理论最大值。 一个原因是段值的较低位编码有关选择器类型的信息。 因此,在65536个可能的选择器值中,只有8191个可用于访问用户模式数据。 这会让你降到32TB。

请注意,有两种方法可以从系统中分配内存,当然,您可以使用C的malloc 隐式地为您的进程分配内存(您的问题标记为c ),但显式映射文件字节。

这种系统中的进程数量是否有限制?

进程包括一个或多个线程,这些线程实际执行进程中的代码(技术上,进程不运行,线程执行)并且用内核线程对象表示。

根据这里进行的一些测试,具有2GB默认地址空间的32位Windows XP系统可以创建大约2025个线程:

线程限制为2025年

但是,在具有4GB分配地址空间的64位Windows XP上运行的32位测试限制创建了接近3204个线程:

64位XP上的32位测试限制创建了3204个线程

但是,确切的线程和进程限制是极其可变的,这取决于很多因素。 线程指定其堆栈大小的方式,进程指定其最小工作集的方式,可用的物理内存量以及系统提交限制。 在任何情况下,您通常不必在现代系统上担心这一点,因为如果您的应用程序确实超出了线程限制,您应该重新考虑您的设计,因为几乎总有其他方法可以用合理的数量来实现相同的目标。

是的,32位系统(2 32字节)上每个进程的虚拟地址空间为4GB。 实际上,实际使用的少量虚拟内存对应于处理器高速缓存,物理内存或磁盘中的位置(或者计算机决定放置东西的任何其他位置)。

从理论上讲(这种行为在常见的操作系统中很常见),如果操作系统决定将所有不适合物理内存的东西放到磁盘上,那么一个进程实际上可以使用它的所有虚拟内存,但这会使程序非常因为每次尝试访问一些未缓存的内存位置时,都必须从磁盘中获取它。

你问你给的图片是否可以增长到4GB。 实际上,你给的图片已经占用了4GB。 这是一种将进程的4GB虚拟内存划分为不同部分的方法。 此外,如果你正在考虑堆和堆栈“增长”,它们并没有真正增长; 他们在分区布局中为它们分配了一定量的内存,并且它们只是利用那些内存(但是它们想要)(堆栈移动指针,堆维护已使用和未使用的内存的数据结构等)。

您是否阅读过维基百科的虚拟内存 , 进程 , 地址空间页面?

你读过哪本关于高级unix编程的书 ? 还是高级linux编程 ?

通常,地址空间是有效的段集(图中不是蓝色)。

另请参见mmap(2)和execve(2)页面。

试试(在Linux系统上)

 cat /proc/self/maps 

 cat /proc/$$/maps 

了解更多。

另见这个问题和这个 问题 。 阅读操作系统:三个简单的部分

当然,内核能够设置一些限制(另请参阅setrlimit(2) syscall)。 它们是资源限制(交换空间,RAM,……)。

回答被忽视的部分……

可以有多少进程限制。 内核保留在虚拟地址空间部分中的所有每进程数据结构(共享,否则您将无法在每个进程中访问内核)占用一些空间。 因此,例如,如果此数据有1GB可用,并且内核中每个进程只需要4KB页面,那么最多可达到25万个进程。 实际上,这个数字通常要小得多,因为事情越复杂,每个过程都会为各种事物保留物理内存。 有关详细信息,请参阅Mark Russinovich关于Windows中进程和线程限制的文章 。