嗨,我是Linux内核开发的新手。因此,希望对下面的语句有一些清晰的说明。
在内存中,每个进程都有一个4GB的虚拟地址空间。
考虑32位架构。进程的用户空间部分可以访问较低的3GB虚拟地址,内核空间部分可以访问上1GB的虚拟地址。
发布于 2015-06-14 10:47:56
简介
与大多数现代操作系统一样,Linux使用大多数现代体系结构(包括x86系列)提供的虚拟页面。
在具有虚拟内存的系统中,物理内存(实际RAM资源)是从系统上运行的进程中抽象出来的。地址空间就是内存可能存在的所有数字。
寻呼
内存可以映射到页面中(放置在一个地址),这是一个内存块的体系结构依赖大小。因此,如果您想要将内存放在某个地址以便进程可以使用它,那么您必须选择一个页面对齐号(页面大小的倍数),并在其中放置至少一个页面。
保护
虚拟内存还允许内存保护,这将设置进程将具有的权限。当一个进程的可执行内存被映射(它执行的指令用来做事情)时,它只被读取/执行。这意味着处理器可以执行该内存,您可以读取它,但不能写入它。
当一个进程从磁盘(在Linux中使用exec系统调用)加载时,它被放置在内存中,其中已经映射了几个内存区域。这些区域是程序、数据部分和堆栈中的可执行代码。该进程可以使用mmap或brk系统调用请求稍后映射的更多内存。
当一个进程试图访问它没有映射的内存时,它会触发臭名昭著的SEGFAULT错误,并且内核会杀死您的程序。其他情况下,硬件会出错,但是程序确实有内存映射,这是因为内核将其取消映射以保存到需要时为止。这里发生的是进程停止运行,内核映射内存,您的进程又开始运行,就像什么都没有发生一样。
地址空间
因此,地址空间的大小只是内存的上限,如果程序将可能的每个地址映射到实际的RAM内存中。
内核部分的一个gig地址空间是关于进程的元数据的,内核会跟踪这些数据。例如,它将保留打开文件的列表,并在进程头中映射内存。它还会将线程头保留在那里。同样,所有这些都不是映射出来的,而是它所需要的。
请注意,每个进程都有自己的地址空间,它从未看到其他进程在这些地址上映射了什么。这样,进程就可以像机器上唯一的进程一样,将内存映射到它选择的任何地址。
还要注意,4gb的数字是因为进行寻址的硬件只支持32位数字,32位数字中最大的数字是2^32 = 4,294,967,296。这是4GB。因此只能将4gb的地址映射到内存中。
这只是一个糟糕的介绍,请做一些谷歌上的虚拟内存。
发布于 2015-06-14 18:14:31
这是否意味着linux中的每个进程都分配了那么多内存空间( 1GB+3GB )?
不是的。所有进程共享相同的内核空间。此外,这些都是最大的理论极限。它们可以进一步受到系统设置、进程设置和页面文件大小的限制。即使系统允许进程增长到最大的一面,进程通常从小进程开始,并且必须增长才能达到最大值。
如果是的话,那么linux中就有数百个进程,那么100*4GB的空间来自系统获得这么多内存空间的地方吗?
请参见上面的。如果允许,这种内存空间将位于页文件(分区)中的磁盘上。
它与内核堆栈和用户堆栈有什么关系?
它们是分开的堆叠。内核堆栈位于内核空间,用户堆栈位于用户空间。处理器在内核模式下执行时使用内核堆栈,在用户模式下使用用户堆栈。作为模式间硬件切换的一部分,开关是自动的。
linux中的每个进程都有内核和用户堆栈吗?
是。每个线程都有一个。内核栈往往很小。
https://stackoverflow.com/questions/30820383
复制相似问题