在没有交换的情况下如何管理分页。如果是这种情况,如何管理页面错误?
我的意思是,如果没有可用的交换,那么如何管理分页。我知道会有两个页面列表 - free_pages 列表和located_pages 列表。当 free_pages 列表中的页面变低时,它会将 LRU 页面从分配的_pages 列表移动到交换分区。我只想知道如果没有交换分区会发生什么。
使用 32 位 x86 PAE Linux 内核时,即使系统有更多 GiB 的可用内存,单个应用程序也不能分配超过 2 GiB,这是真的吗?64 位 x86 Linux 内核是否放宽了此限制?
我对 TLDP 中虚拟内存的解释完全困惑:
http://www.tldp.org/LDP/tlk/kernel/processes.html#tthFtNtAAB
他们说:
每个单独的进程都在其自己的虚拟地址空间中运行,除非通过安全的内核管理机制,否则无法与另一个进程交互。
我的“自己的虚拟地址空间”在 32 位模式下读取为自己的 4Gb RAM:0000:0000 - FFFF:FFFF。但他们不是那个意思,对吧?如果两个进程指向虚拟地址 1111:1111,它们意味着相同的物理地址,那么所有进程共享相同的 4 Gb 虚拟地址空间?
此外,我在这里阅读了有关 Windows 的内容,它们确实为每个进程提供了单独的虚拟地址空间,为用户模式提供了单独的 2Gb RAM,为内核模式提供了共享的 2Gb,因此两个不同的进程都可以指向 1111:1111,它映射到不同的物理内存。他们吗?:)
更新:我的问题的插图。哪些图片适合 Linux:
情况1:

案例二

我运行相当定期从内存不足遭受桌面系统,这促使我去研究什么导致该问题摆在首位。
问题是,没有一个进程会占用内存,但系统并未将其显示为可用。更重要的是,系统确实进行了交换,因此看起来内存压力是真实的。令人费解的是,在我注销并再次退出后,使用情况恢复正常(使用了约 1GB),因此它看起来像是用户空间和内核之间的一些奇怪的交互,而不是内存泄漏。
简而言之:
free,不包括缓存/缓冲区:3173960 kB这给出了3173960-2413952-158968-75992 = 525048 kB未计入的内存使用量。
我缺少什么或不计算什么?
应用程序内存使用总和:
# smem -t | sed -n '1p;$p'
PID User Command Swap USS PSS RSS
108 6 244524 2413952 2461340 2648488
Run Code Online (Sandbox Code Playgroud)
报告的内存使用情况free:
# free -k
total used free shared buffers cached
Mem: 4051956 3449748 602208 0 26548 249240
-/+ buffers/cache: 3173960 877996
Swap: 4051952 242592 3809360
Run Code Online (Sandbox Code Playgroud)
一般内存统计:
# cat /proc/meminfo
MemTotal: 4051956 …Run Code Online (Sandbox Code Playgroud) 我尝试从以下两个来源找出共享内存段的范围,即进程内存布局中的内存映射段。
从https://manybutfinite.com/post/anatomy-of-a-program-in-memory/,我找到了一个进程的内存布局图
内存映射段和堆会一直增长直到它们相遇吗?
或者两个段中的每一个都有一个限制,类似于堆栈段的 RLIMIT_STACK?
来自 Linux 编程接口
为了为堆和堆栈增长留出空间,共享内存段从虚拟地址 0x40000000 开始附加。映射映射(第 49 章)和共享库(第 41 和 42 章)也放置在该区域中。(根据内核版本和进程的 RLIMIT_STACK 资源限制的设置,共享内存映射和内存段的默认位置有一些变化。)地址 0x40000000 被定义为内核常量 TASK_UNMAPPED_BASE。
共享内存段是否从 TASK_UNMAPPED_BASE 开始并向上增长?
请注意,上图显示共享内存段向下增长,那么它是向上增长还是向下增长?
谢谢。
所以我一直认为 MMU 是将地址转换为物理地址的 unix 内核的一部分,但在 MMU wiki 页面中,它说它是一个通常有自己内存的计算机硬件,但该页面并没有太多谈论 Unix/Linux 操作系统
所以我很困惑,是否所有的翻译都发生在硬件和内核中不做任何翻译?基本上操作系统对真实的物理地址一无所知?
我问的是基于 Unix 的操作系统,但如果您了解其他操作系统以及 Windows,或者它是否在现代计算机中是通用的,请告诉我,谢谢。
这是在gdb中查看进程的虚拟内存的结果;我对此有一些疑问:
为什么虚拟内存的某些部分是重复的?比如我们的程序(stack6)和libc库重复了4次;如果他们把它们分成不同的部分,那为什么呢?为什么不把它们放在一起呢?
顶部路径(/opt/pro...)是我们虚拟内存的指令部分(文本部分)并且只包含指令吗?
为什么4个libc的大小不同?偏移量有什么关系,如果我们已经有了大小和起始地址,那么偏移量是什么?
数据、bss、内核和堆部分在哪里,为什么上图中的某些部分没有关于它们的信息?gdb 中是否有更好的选项可以实际显示所有部分?
有没有比 gdb 更好的程序可以更好地显示我们进程的虚拟内存部分?我只想对实际的虚拟内存有一个很好的视觉效果,哪个调试程序提供了最好的结果。
我提到的部分:
我想知道 Linux 在哪里存储页表。它在内核虚拟内存中吗?
这似乎与虚拟内存系统有关。但我是新手,所以如果我走错了方向,请告诉我。为了自己回答这个问题,我从一本书中读了几行说:
(23.2 第 8 页)
... Linux 虚拟地址空间由用户部分和内核部分组成...
...内核部分在进程间是相同的。
那么内核提供的地址空间在某种意义上是进程共享的空间吗?那么如果页表被放在内核虚拟内存中,这是否意味着进程可以共享它们的页表?
我读过的书:http : //www.ostep.org
例如grep,如果一个程序当前正在运行,而用户执行另一个实例,那么这两个实例是否共享.text它们之间的只读部分以节省内存?主要可执行文本的共享是否与共享库类似?
这种行为是否在 Linux 中表现出来?如果是这样,其他Unices 也这样做吗?
如果这不是在 Linux 中完成的,那么实现通常作为共享库并行运行多个实例的可执行文件是否有任何好处,调用的可执行文件只需调用库中的主函数?
我总是读到 Linux 内核不可分页。
如果我没记错的话,Windows 会在分页部分(分页池)和非分页部分(非分页池)中分配系统虚拟内存。
非分页部分直接映射到物理内存并一直留在那里,因为它负责处理内核必须完成的最重要的任务,而不太重要的部分可能不会。相反,Linux 内核被划分为可加载的模块,但我没有收集到有关如何实现这些模块的信息。
我不明白它们是否被分页,因此您可以暂时将它们传输到磁盘。我通常读到的是我们可以通过卸载它们来“释放”内存,这对我来说仍然是什么意思。
当我在这篇文章中写下“分页”或“可分页”时,我暗示您可以在磁盘上交换这些页面。我解决了这个问题,因为通常 Linux 内核被认为是分页的,但它不能被换出
virtual-memory ×10
kernel ×4
linux ×4
process ×3
linux-kernel ×2
memory ×2
swap ×2
debugging ×1
elf ×1
executable ×1
gdb ×1
hardware ×1
memory-leaks ×1
pae ×1
ram ×1