您好我是Linux内核开发的新手。所以想要明确以下陈述。
* GT;在内存中,每个进程都有4GB的虚拟地址空间
考虑使用32位架构。较低的3GB虚拟地址是 可访问进程的用户空间部分和高1GB 内核空间部分可以访问。*
答案 0 :(得分:3)
与大多数现代操作系统一样,Linux使用大多数现代架构提供的虚拟页面,包括x86系列。
在具有虚拟内存的系统中,物理内存(实际RAM资源)是从系统上运行的进程中抽象出来的。地址空间就是内存可能
的所有数字。内存可以映射(放在地址) pages ,这是内存块的体系结构相关大小。因此,如果您想将内存放在某个地址以便进程可以使用它,那么您必须选择页面对齐的数字(页面大小的倍数)并在那里放置至少一页。
虚拟内存还允许内存保护,用于设置进程具有的权限。当映射进程的可执行内存(它执行的指令来执行操作)时,它只能被读/执行。这意味着处理器可以执行该内存,您可以读取它,但不能写入它。
当从磁盘加载进程时(在Linux中使用exec
系统调用),它将被放置在内存中,并且已映射了几个内存区域。这些区域是程序,数据部分和堆栈中的可执行代码。该进程可以使用mmap
或brk
系统调用请求稍后映射更多内存。
当进程尝试访问内存时,它没有映射,它会触发臭名昭着的SEGFAULT
错误,内核会终止你的程序。其他时候,硬件会出错但程序确实有内存映射,这是因为内核取消映射它以保存它直到需要它。这里发生的是进程停止运行,内核重新映射内存,并且您的进程再次开始运行,就像没有发生任何事情一样。
因此,如果程序将每个地址映射到实际的RAM内存,地址空间的大小就是内存的上限。
内核部分的一个gig地址空间是关于内核跟踪的进程的元数据。例如,它将保留打开文件的列表,并在进程头中保留映射内存。它还会保留线程头。同样,所有这些都没有映射,只是它所需要的。
请注意,每个进程都有自己的地址世界,它永远不会看到另一个进程在这些地址上映射的内容。通过这种方式,进程可以表现为机器上唯一的进程,将内存映射到它选择的任何地址。
另请注意,4gb数字是因为执行寻址的硬件仅支持32位数字,32位数字中最大的数字是2 ^ 32 = 4,294,967,296。这是4 GB。因此,人们只能将4gb的地址映射到内存中。
这只是一个蹩脚的介绍,请在虚拟内存上进行一些谷歌搜索。
答案 1 :(得分:0)
这是否意味着linux中的每个进程都分配了大量内存空间1GB + 3GB?
没有。所有进程共享相同的内核空间。另外,这些是最大理论极限。系统设置,进程设置和页面文件的大小可以进一步限制它们。即使系统允许流程增长到最大程度,流程通常也会从小规模开始,并且必须增长到达最大值。
如果是,则linux中有数百个进程,因此系统获得如此大的内存空间需要100 * 4GB空间?
见上文。如果允许,这样的内存空间将位于页面文件(分区)中的磁盘上。
它与内核堆栈和用户堆栈的关系是什么?
它们是独立的堆栈。内核堆栈位于内核空间中,用户堆栈位于用户空间中。处理器在内核模式下执行时使用内核堆栈,在用户模式下使用用户堆栈。该开关是自动的,作为模式之间硬件切换的一部分。
linux中的每个进程都有内核和用户堆栈吗?
是。每个线程都有一个。内核堆栈往往很小。