当我们增加进程的帧数时,页面错误的数量应该会减少,但有时页面错误会增加(Belady 的异常)。如何避免这种情况?
正如了解JVM 内存分配和 Java 内存不足:堆空间 中所述,分配堆空间时,JVM 不区分物理内存和虚拟内存。当java对象的内存分配和计算开始发生时,JVM开始区分虚拟内存和物理内存。如果有足够的交换空间(在 Linux 机器上),为什么会发生内存不足错误?JVM 不应该简单地使用交换空间来完成计算吗?尽管速度很慢。
例如:RAM:14GB,交换空间:10GB
如果一个java应用程序需要20GB的空间,它不能利用交换空间(虚拟内存)来完成应用程序的运行吗?
对于 Java 应用程序来说,堆空间和虚拟内存之间的相互作用是什么?
我知道如果一个页面已被访问,它将设置访问位,如果已被写入,则脏位也将被设置。但我不清楚这些位如何影响 TLB/TLB 缓存?OSDEV还有以下段落
当条目标记为存在时将访问位或脏位从 1 更改为 0 时,建议使关联页无效。否则,由于 TLB 缓存,处理器可能不会在后续读/写时设置这些位。
在什么情况下您会将脏位和访问位从 1 更改为 0?
我正在做一个业余爱好操作系统项目,并试图设置虚拟内存。我在 x86 架构中还有另一个使用页表的项目,但我现在正在学习 ArmV8。
现在,用于寻址的最大位数是 48 [1]。最后 12 到 16 位“按原样”用于在所选区域内进行索引(取决于选择的颗粒大小[2])。
我只是不明白我们如何获得这些中间位。显然,文档显示使用了中间表[3],但尚不清楚如何使用这些表。
在下图的前半部分中,我们看到使用 4k 颗粒并使用 38 个地址位的地址转换。

我完全无法理解这个图像。“偏移量”,例如位 38 到 30,指向 L1 表中的条目。该表是如何定义的以及在哪里定义的?
我认为正在发生的是,这是一个 12+8+8+8 地址转换方案。从右边开始,12 位查找 4096 内存块内的偏移量。右边是 L3 的 8 位,这意味着 L3 索引 256 个 4096 字节 (1MB) 的块。右边的 L2 也有 8 位,因此有 256 个 (256*4096) 条目,每个 L2 条目总计 256MB。L2 的右侧是 L1,也是 8 位,256 个 256MB 的条目意味着总可寻址内存为 64GB 物理 RAM。
我认为这是不正确的,因为这只允许内存的 1:1 映射。每个表描述符需要携带一些访问标志等等。因此回到问题:这些表是如何定义的。每个偏移部分都是 8 位,这不足以包含转换表的地址。
无论如何,我完全迷失了。如果有人能给我一个关于如何完成翻译表行走的“简单英语”解释,我将不胜感激?一张图表会很好,但可能太费力了,我会制作一个图表并在之后分享以帮助我综合信息。或者至少,如果有人有一个好的视频/指南的链接,其中的信息没有完全混淆?
以下是我查阅过的材料清单:
https://developer.arm.com/documentation/den0024/a/The-Memory-Management-Unit/Translated-a-Virtual-Address-to-a-Physical-Address https://forums.raspberrypi.com/viewtopic .php?t=227139
请解释RVA和VA的含义
我正在编写一个程序,出于性能原因使用共享内存(套接字和管道作为替代品已被评估,并且它们对我的任务来说不够快,一般来说任何涉及副本的IPC方法都太慢).在共享内存区域中,我正在编写许多固定大小的结构.有一个程序负责将结构写入共享内存,以及许多从中读取的客户端.但是,每个结构中都有一个客户端需要写入的成员(引用计数,它们将以原子方式更新).所有其他成员都应该只读给客户.
由于客户端需要更改该成员,因此无法将共享内存区域映射为只读.但他们也不应该修改其他成员,因为这些程序是用C++编写的,所以内存损坏是可能的.理想情况下,一个客户端应该尽可能地使另一个客户端崩溃.我只担心有问题的客户,而不是恶意客户,所以允许不完美的解决方案.
我可以尝试通过声明他们用作const的标头中的成员来阻止客户端覆盖,但这不会阻止内存损坏(缓冲区溢出,错误的强制转换等)被覆盖.我可以插入金丝雀,但是我必须经常支付检查它们的费用.
我可以在一个单独的映射只写页面中存储指向实际数据的指针,而不是直接存储引用计数成员,同时将结构保留在只读映射页面中.这将起作用,如果我尝试写入指向的数据,操作系统将强制我的应用程序崩溃,但是在尝试编写无锁算法时间接存储可能是不合需要的,因为需要遵循另一级别的间接可以改变是否可以原子地完成.
有没有办法标记较小的内存区域,以便写入它们会导致您的应用程序爆炸?有些平台有硬件观察点,也许我可以激活其中一个内联汇编,但我只能在32位x86上一次只限4个,每个只能覆盖部分结构,因为它们有限到4个字节.这也使我的程序调试痛苦;)
编辑:我发现这张相当令人眼花缭乱的纸张,但不幸的是它需要使用ECC内存和修改过的Linux内核.
c++ reference-counting shared-memory virtual-memory memory-corruption
在分页分段系统中,我们有虚拟地址32位和12位用于偏移,11位用于段,9位用于页码.我们如何计算页面大小,最大段大小和最大段大小?
希望标题清楚.我有一块通过mmap()获得的内存.过了一段时间,我得出结论,我不再需要这个范围内的数据.不过,我仍然希望保持这个范围.也就是说,我不想调用mummap().我想成为一个好公民,而不是让系统交换超出需要.
有没有办法告诉Linux内核,如果给定的页面是由物理页的支持和如果内核决定它需要一个物理页面,也懒得写一个页面交换?
我想在幕后这个神奇的函数调用会破坏给定虚拟页面和物理页面之间的任何映射(如果存在),而不首先写入交换.
我使用VirtualQuery迭代我的进程内存,我想知道一定的内存范围是由谁拥有的.可执行文件或者其他一些dll,并获取它的名称.
有没有办法可以找到答案?
我怎样才能让一个程序中使用虚拟内存的Windows?
我有一个很长的perl脚本,使用6GB +内存并增加.我的机器只有8GB或RAM.它可能是由模块中的内存泄漏引起的,但现在我无能为力.
是否有可能使其使用虚拟内存,或者Windows仅仅是由它控制?
virtual-memory ×10
paging ×2
architecture ×1
arm64 ×1
armv8 ×1
c++ ×1
compilation ×1
executable ×1
heap-memory ×1
java ×1
jvm ×1
linux ×1
mmap ×1
mmu ×1
pagefile ×1
perl ×1
swap ×1
tlb ×1
winapi ×1
windows ×1
x86 ×1