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

时间:2012-03-01 07:04:03

标签: c memory-management

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

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

enter image description here

4 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:2)

您是否阅读过维基百科的virtual memoryprocessaddress space页?

您读过哪本关于advanced unix programming的书?还是advanced linux programming

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

另请参阅mmap(2)execve(2)页。

尝试(在Linux系统上)

cat /proc/self/maps

cat /proc/$$/maps

了解更多。

另请参阅this questionthis。阅读Operating Systems: Three Easy Pieces

当然,内核可以设置一些限制(另请参阅setrlimit(2)系统调用)。它们是资源限制(交换空间,RAM,......)。

答案 2 :(得分:2)

这可以增长到4GB吗?

  

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

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

  

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

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

此类系统中的进程数量是否有限制?

  

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

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

Thread Limit of 2025

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

32bit test limit on 64 bit XP created 3204 threads

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

答案 3 :(得分:-1)

回答被忽视的部分......

可以有多少进程限制。内核保留在虚拟地址空间的一部分中的所有每进程数据结构(共享,否则您将无法在每个进程中访问内核)占用一些空间。因此,例如,如果此数据有1GB可用,并且内核中每个进程只需要4KB页面,那么最多可达到25万个进程。在实践中,这个数字通常要小得多,因为事情更复杂,每个过程都有为各种事物保留的物理内存。例如,请参阅Mark Russinovich's article on process and thread limits in Windows了解更多详情。