你好,我是新手Linux内核开发者。所以想要对以下陈述有一些清晰的理解。
*> 在内存中,每个进程被赋予4GB的虚拟地址空间
考虑到32位架构。低3GB虚拟地址可以访问进程的用户空间部分,而高1GB可以访问内核空间部分。
- 这是否意味着Linux中的每个进程都被分配了1GB+3GB的内存空间?
- 如果是的话,那么Linux中有数百个进程,系统从哪里获得如此多的内存空间?
- 它与内核栈和用户栈有什么关系?
- Linux中的每个进程是否都有内核和用户栈?
你好,我是新手Linux内核开发者。所以想要对以下陈述有一些清晰的理解。
*> 在内存中,每个进程被赋予4GB的虚拟地址空间
考虑到32位架构。低3GB虚拟地址可以访问进程的用户空间部分,而高1GB可以访问内核空间部分。
Linux和大多数现代操作系统一样,使用由大多数现代架构提供的虚拟页。其中包括x86系列。
在具有虚拟内存的系统中,物理内存(实际RAM资源)与运行在系统上的进程是相互独立的。地址空间只是内存可能存在的所有数字。
内存可以映射(放置在一个地址上)到页面,它是内存块的体系结构相关大小。因此,如果您想将内存放置在某个地址上以便进程可以使用它,那么您必须选择一个对齐页面的数字(页面大小的倍数),并至少在那里放置一个页面。
虚拟内存也允许内存保护,从而设置进程将具有的权限。当映射进程的可执行内存(执行操作的指令)时,它是只读/执行的。这意味着处理器可以执行该内存,您可以读取它,但是您不能写入它。
当从磁盘加载进程时(在Linux中使用exec
系统调用),它会被放置在内存中,已经映射了几个内存区域。这些区域是程序的可执行代码、数据部分和堆栈。进程可以通过使用mmap
或brk
系统调用来请求映射更多内存。
当进程尝试访问它没有映射的内存时,它会触发臭名昭著的SEGFAULT
错误,并且内核将终止您的程序。其他情况下,硬件会发生故障,但程序已经有了映射的内存,这是因为内核取消了映射以将其保存到需要时再重新映射。在这里发生的情况是进程停止运行,内核重新映射内存,您的进程再次开始运行,就像什么都没发生过一样。
因此,地址空间的大小只是如果程序将每个可能的地址都映射到实际RAM内存,则内存的上限。
内核部分的1GB地址空间与内核跟踪的进程元数据有关。例如,它将在进程标题中保留打开的文件列表和映射内存。它还将在那里保留线程标题。同样,仅映射所需的内容,而不是全部。
请注意,每个进程都有自己的地址空间,它从不看到其他进程在这些地址上映射了什么。这样,进程可以像是机器上唯一的进程一样运行,将内存映射到任何所选地址。
还要注意,4GB数字是因为进行寻址的硬件仅支持32位数字,32位数字可以容纳的最大数字是2^32= 4,294,967,296。这是4GB。因此,只能将4GB的地址映射到内存中。
这只是一个糟糕的介绍,请在虚拟内存上做一些搜索。