我想知道提交大小(在任务管理器中可见)和虚拟大小(在SysInternals的Process Explorer中可见)之间的确切区别.
Process Explorer中的Virtual Size参数看起来更准确地指示进程的总虚拟内存使用情况.但是,提交大小始终小于虚拟大小,我想它不包括进程使用的所有虚拟内存.我希望有人解释这些参数中包含的内容.
我有一个通过mmap使用获得的内存段MAP_ANONYMOUS.
如何分配引用第一个相同大小的第二个内存段并在Linux中进行复制写入(目前正在使用Linux 2.6.36)?
我想要与完全相同的效果fork,只是没有创建一个新的过程.我希望新映射保持在同一个进程中.
整个过程必须在原始页面和复制页面上都是可重复的(就像父母和孩子一样会继续fork).
我不想分配整个段的直接副本的原因是因为它们是几千兆字节大而且我不想使用可以写入时复制的内存.
我尝试过的:
mmap该段分享,匿名.复制mprotect它为只读并创建第二个映射remap_file_pages也是只读的.
然后使用libsigsegv拦截写入尝试,手动制作页面的副本然后mprotect两者进行读写.
诀窍,但非常脏.我本质上是实现自己的VM.
令人遗憾的是,当前的Linux不支持mmaping /proc/self/mem,否则MAP_PRIVATE就可以实现映射.
写时复制机制是Linux VM的一部分,必须有一种方法可以在不创建新进程的情况下使用它们.
作为一个注释: 我已经在Mach VM中找到了合适的机制.
以下代码在我的OS X 10.7.5上编译并具有预期的行为:
Darwin 11.4.2 Darwin Kernel Version 11.4.2: Thu Aug 23 16:25:48 PDT 2012; root:xnu-1699.32.7~1/RELEASE_X86_64 x86_64 i386
gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#ifdef __MACH__
#include …我在课本中读到堆栈通过减少内存地址而增长; 也就是说,从较高地址到较低地址.这可能是一个糟糕的问题,但我没有把这个概念弄好.你可以解释吗?
所以Belady的Anomaly指出,当使用FIFO页面替换策略时,当添加更多页面空间时,我们会有更多的页面错误.
我的直觉说我们应该减少或最多相同数量的页面错误,因为我们添加了更多的页面空间.
如果我们将FIFO队列视为管道,添加更多页面空间就像使管道更大:
 ____
O____O  size 4
 ________
O________O  size 8
那么,为什么会出现更多页面错误?我的直觉说,使用更长的管道,你需要花费更长的时间才能开始出现页面错误(因此,使用无限管道,你没有页面错误)然后你会遇到同样多的页面错误,就像通常与较小的管道一样.
我的推理出了什么问题?
请考虑以下情况:内核耗尽了物理RAM并需要换出页面.它选择最近最少使用的页面框架,并希望将其内容交换到磁盘并将该框架分配给另一个进程.
困扰我的是,这个页面框架已经映射到一般来说,几个(相同的)几个进程的页面.内核必须以某种方式找到所有这些进程并将页面标记为已换出.它是如何实现的?
谢谢.
编辑:问题的插图:
在交换过程1和2之前有一个共享的Page 1,它位于物理内存帧1中:

现在,系统中的内存耗尽,内核通过从第1帧交换第1页并将其替换为第2页来为进程3分配内存.为了做到这一点,它必须
1)找到所有流程,参考第1页(在我们的案例中为流程1和流程2)
2)修改其页表条目,将"Present"位设置为0并在Swap中设置Page 1位置

所以,我不知道,第1步是如何进行的.内核不能只是迭代地查看每个进程的页表,以便找到指向第1帧的页表条目.应该存在从页框到页表条目的某种反向映射.
答案是:
"页表管理最重要和最重要的变化是引入了反向映射(rmap).将其称为"rmap"是故意的,因为它是"首字母缩略词"的常见用法,不应与-rmap混淆由Rik van Riel开发的树,它对库存VM的更多改动而不仅仅是反向映射.
在一个句子中,rmap授予定位所有PTE的能力,这些PTE仅在给定结构页面的情况下映射特定页面.在2.4中,找到映射共享页面的所有PTE(例如内存映射共享库)的唯一方法是线性搜索属于所有进程的所有页表.这太昂贵了,Linux试图通过使用交换缓存来避免这个问题(参见11.4节).这意味着对于许多共享页面,无论页面使用时间和使用模式如何,Linux都可能必须更换整个进程.2.6而是有一个与每个结构页面相关联的PTE链,可以遍历该页面以从引用它的所有页面表中删除页面.这样,LRU中的页面可以以智能方式交换出来,而无需交换整个过程."
从了解Linux内存管理,"Linux2.6中的新功能"
处理器x86/x86_64中使用哪种寻址在L1,L2和L3(LLC)中进行缓存 - 物理或虚拟(使用PT/PTE和TLB)以及PAT(页面属性表)对它有何影响?
在这种情况下,驱动程序(内核空间)和应用程序(用户空间)之间是否存在差异?
简短回答 - 英特尔使用虚拟索引,物理标记(VIPT)L1缓存:线程之间的数据交换将用于在具有HT的一个Core上执行什么?
8-way用于定义的高速缓存中Set需要低12 bits,这在virt和phys中是相同的)我对操作系统中的物理/逻辑/虚拟地址这个术语感到有点困惑(我使用的是Linux-open SUSE)
这是我的理解:
物理地址 - 当处理器处于系统模式时,处理器使用的地址是物理地址.
逻辑地址 - 当处理器处于用户模式时,使用的地址是逻辑地址.通过添加带有偏移值的基址寄存器,这些都可以映射到某个物理地址.它在某种程度上提供了一种内存保护.
我遇到过讨论,虚拟和逻辑地址/地址空间是相同的.这是真的吗?
非常感谢任何帮助.
我有现有的代码,它采用一个列表struct page *并构建一个描述符表来与设备共享内存.该代码的上层当前需要一个与vmalloc用户空间分配的缓冲区,并用于vmalloc_to_page获取相应的缓冲区struct page *.
现在上层需要处理各种内存,而不仅仅是通过内存获得vmalloc.这可能是一个缓冲区kmalloc,内核线程堆栈中的指针,或其他我不知道的情况.我唯一的保证是这个上层的调用者必须确保所讨论的内存缓冲区在该点被映射到内核空间(即此时buffer[i]所有人都可以访问它0<=i<size).如何获得struct page*对应于任意指针的?
把它放在伪代码中,我有这个:
lower_layer(struct page*);
upper_layer(void *buffer, size_t size) {
    for (addr = buffer & PAGE_MASK; addr <= buffer + size; addr += PAGE_SIZE) {
        struct page *pg = vmalloc_to_page(addr);
        lower_layer(pg);
    }
}
我现在需要改变upper_layer以应对任何有效的缓冲区(不改变lower_layer).
我发现virt_to_page,哪个Linux设备驱动程序指示"逻辑地址,[不]内存vmalloc或高内存".此外,is_vmalloc_addr测试地址是否来自vmalloc,并virt_addr_valid测试地址是否是有效的虚拟地址(饲料virt_to_page包括kmalloc(GFP_KERNEL)和内核堆栈).那么其他情况呢:全局缓冲区,高内存(有一天它会来,虽然我现在可以忽略它),可能还有其他我不知道的类型?所以我可以将我的问题重新表述为:
我的理解是,影子页面表消除了模拟VM内部物理内存的需要.
即.
代替:
客户操作系统 - > VMM +虚拟物理内存 - >主机操作系统 - >主机硬件
只是:
客户操作系统 - > VMM - >主机操作系统 - >主机硬件
影子页表只允许进程正确访问主机硬件的内存.我也不明白页面错误是如何工作的(或者由于所有物理内存都由主机处理,主机负责页面错误,交换等).
我熟悉MIPS架构,它有一个软件管理的TLB.因此,您(操作系统)想要存储页表和页表条目的方式和位置完全取决于您.例如,我做了一个带有单个倒置页表的项目; 我看到其他人在每个进程中使用2级页表.
但x86的故事是什么?据我所知,TLB是硬件管理的.x86告诉你,"嘿,这是你目前使用的页表条目需要去[物理地址范围]"?但是等等,我一直认为x86使用多级页面表,所以它会告诉你在哪里放置第一级别的东西......?我糊涂了.
谢谢你的帮助.
virtual-memory ×10
linux-kernel ×2
x86 ×2
c ×1
caching ×1
callstack ×1
kernel ×1
linux ×1
memory ×1
mmu ×1
page-fault ×1
page-tables ×1
stack ×1
tlb ×1
windows ×1