Articles of 虚拟内存

在linux中计算页面错误导致混淆结果

我正在编写程序来计算Linux系统中页面错误的时间。 更准确地说,内核执行函数__do_page_fault 。 不知何故,我写了两个全局variables,名为pfcount_at_beg和pfcount_at_end ,当函数__do_page_fault在函数的不同位置执行时会增加一次。 为了说明,修改的函数如下所示: unsigned long pfcount_at_beg = 0; unsigned long pfcount_at_end = 0; static void __kprobes __do_page_fault(…) { struct vm_area_sruct *vma; … // VARIABLES DEFINITION unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; pfcount_at_beg++; // I add THIS … … // ORIGINAL CODE OF THE FUNCTION … pfcount_at_end++; // I add THIS } […]

使用端口映射I / O时是否使用虚拟内存?

如果我有一个内存映射的I / O设备,并且我想写一个位于地址0x16D34这个设备的寄存器,那么0x16D34地址实际上是一个虚拟地址,并且CPU将首先将它翻译成一个物理地址,然后将数据写入物理地址。 但是端口映射的I / O设备(例如:一个串口)呢,所以如果我想写一个地址为0x3F8的串口的寄存器, 0x3F8地址是物理地址还是虚拟地址? 编辑:我在x86架构。

malloc在不同的机器上performance不同

当运行一个程序,试图在不同的机器上超过RSS时,我看到完全不同的行为。 代码是这样的: … char** s = (char**)malloc(10000*sizeof(char*)); for (i = 0; i < 10000; i++){ s[i] = (char*)malloc(1000*1000*sizeof(char)); if (s[i] == NULL) { printf("cannot allocate memory for s[%d]",i); exit(1); } } int j = 0; while(1){ for (i = 0; i < 10000; i++){ for (j = 0; j < 1000*1000; j++) { s[i][j] = […]

Linux:pipe理我的进程中的虚拟内存映射以进行快速仿真

最近我发现很多仿真器很慢,因为它们不得不模拟CPU而且仿真器件的内存。 当设备具有内存映射I / O,虚拟内存或只是未使用的地址空间时,每个内存访问都必须用软件模拟。 我觉得如果操作系统通过虚拟内存为我们做了这个,可能会快很多。 为了简单起见,我将使用Game Boy仿真作为示例,但显然这种方法对于更新,更强大的机器会更好。 Game Boy的内存映射大概是: 0x0000 – 0x7FFF:映射到磁带ROM 大多数墨盒都具有0x0000 – 0x3FFF固定和0x4000 – 0x7FFF银行 – 开关通过写入到0x2000 0x8000 – 0x9FFF:videoRAM(仅当当前不呈现时才可访问) 0xA000 – 0xBFFF:映射到盒式磁带(通常由电池供电的RAM) 0xC000 – 0xDFFF:内部RAM(0xD000 – 0xDFFF在GB颜色上被切换) 0xE000 – 0xFDFF:内部RAM的镜像 0xFE00 – 0xFE9F:对象属性存储器(sprite RAM) 0xFEA0 – 0xFEFF:未映射(打开总线或某些东西,不确定) 0xFF00 – 0xFF7F:内存映射I / O(音响系统,video控制等) 0xFE80 – 0xFFFF:内部RAM 所以传统的模拟器必须翻译每一个内存访问,如: if(addr < 0x4000) return rom[addr]; else […]

如果fork()和fork(subprocess)进程退出,那么所有的VM页面在父进程中仍然标记为COW?

在Linux上,如果fork()和分叉(子)进程退出,那么所有的虚拟内存页面仍然在父文件中被标记为copy-on-write? 我认为这些页面将保持标记为COW,否则任何其他操作可能会非常昂贵,可能需要每页参考计数和其他昂贵的簿记。 但是我有一天在想,如果我分叉一个进程来执行当前进程的“稳定快照”中的一些代码。 subprocess退出时会发生什么? 是否将父级保留中的所有内存页标记为写入时复制? 这意味着,在一个拥有大量虚拟内存的进程(如128GB +)中,如果只执行一些代码几分钟,会导致父进程中的性能下降,几个小时甚至几天之后(更不用说叉子本身这将不便宜。) 我只是好奇在Linux上的实际行为(我不知道如何testing它)。

虚拟内存和sbrk

在32位Linux系统上,一个进程可以访问高达4 GB的虚拟地址空间; 然而,在保留任何这些方面,程序在不同程度上似乎是保守的。 所以一个使用malloc的程序偶尔会通过系统调用sbrk / brk来增长其数据段。 即使这些网页尚未在物理内存中声明。 我不完全明白的是,为什么我们首先需要明白,为什么不给我4 GB的地址空间,避免任何sbrk调用,直到我们触及/声称这些块,它本质上是一个自由的操作权?

基于哪个Linux交换进程内存从RAM到交换文件的确切条件是什么?

我的服务器有8G的内存和8Gig的交换文件configuration。 我有内存密集型应用程序运行。 这些应用程序有高峰负载,在这期间我们发现交换使用率增加 大约使用1 GIG交换。 我有另一台服务器,内存4Gigigs和8Gig的交换和类似的内存密集型应用程序运行。 但是这里的交换使用是非常可以忽略的。 大约100 MB。 我想知道什么是确切的条件或一个粗略的公式,基于哪个Linux将交换RAM中的进程内存交换文件。 我知道它基于交换因素。 还有什么是基于? 交换文件大小? 任何指向Linux内核文档/源代码的指针都会很好。

Linux下的共享库加载地址

我对共享库有一个很大的疑问。 我研究的是,不同进程共享的库的虚拟地址对于所有这些进程是相同的。 但我试图通过使用proc文件系统通过以下一组命令来查看相同的内容: $ cat /proc/*/maps | grep /lib/libc-2.12.1.so 输出是: 0025a000-003b1000 r-xp 00000000 08:07 1046574 /lib/libc-2.12.1.so 003b1000-003b2000 —p 00157000 08:07 1046574 /lib/libc-2.12.1.so 003b2000-003b4000 r–p 00157000 08:07 1046574 /lib/libc-2.12.1.so 003b4000-003b5000 rw-p 00159000 08:07 1046574 /lib/libc-2.12.1.so 0086d000-009c4000 r-xp 00000000 08:07 1046574 /lib/libc-2.12.1.so 009c4000-009c5000 —p 00157000 08:07 1046574 /lib/libc-2.12.1.so 009c5000-009c7000 r–p 00157000 08:07 1046574 /lib/libc-2.12.1.so 009c7000-009c8000 rw-p 00159000 […]

堆的界限是什么?

给定过程中堆的界限是什么? 我明白,这个问题可能没有简单的答案,所以我特别感兴趣的答案如下: 在AMD64的Linux下,是否有标准堆大小/位置的64位进程? 如果我正在实现一个语言运行时,我怎么能find我不允许堆的地方(再次,Linux / AMD64) 有没有一种便捷的方式来查找应用程序的开始/结束位置?

如何在Linux 64bit机器上find你的数据结构实现的内存布局

在本文中, http://cacm.acm.org/magazines/2010/7/95061-youre-doing-it-wrong/fulltext 作者讨论了2种数据结构(二进制堆和B堆)的内存布局,并比较了如何比其他内存布局更好(图5和图6)。 我想在这方面获得经验。 我有一个N-Ary树的实现,我想找出我的数据结构的内存布局。 想出一个像文章中那样的内存布局的最佳方式是什么? 其次,我认为如果它是基于数组的实现,则更容易识别内存布局。 如果树的实现使用指针,那么我们有什么工具或需要什么样的方法来映射它的内存布局?