内存表大小

时间:2015-10-26 22:33:30

标签: c++ memory x86

我有文件,描述了进程的32位虚拟地址空间的结构。例如:

  • 08048000-08053000 r-xp 00000000 08:03 18877 / usr / bin / cat
  • 08053000-08054000 r - p 0000a000 08:03 18877 / usr / bin / cat
  • 08054000-08055000 rw-p 0000b000 08:03 18877 / usr / bin / cat
  • 091e3000-09204000 rw-p 00000000 00:00 0 [heap]
  • 4f2d0000-4f2ef000 r-xp 00000000 08:03 1857 /usr/lib/ld-2.15.so
  • 4f2ef000-4f2f0000 r - p 0001e000 08:03 1857 /usr/lib/ld-2.15.so
  • 4f2f0000-4f2f1000 rw-p 0001f000 08:03 1857 /usr/lib/ld-2.15.so
  • 4f2f7000-4f4a2000 r-xp 00000000 08:03 1858 /usr/lib/libc-2.15.so
  • 4f4a2000-4f4a3000 --- p 001ab000 08:03 1858 /usr/lib/libc-2.15.so
  • 4f4a3000-4f4a5000 r - p 001ab000 08:03 1858 /usr/lib/libc-2.15.so
  • 4f4a5000-4f4a6000 rw-p 001ad000 08:03 1858 /usr/lib/libc-2.15.so
  • 4f4a6000-4f4a9000 rw-p 00000000 00:00 0
  • b75c0000-b77c0000 r - p 00000000 08:03 57661 / usr / lib / locale / locale-archive
  • b77c0000-b77c1000 rw-p 00000000 00:00 0
  • b77d9000-b77da000 rw-p 00000000 00:00 0
  • b77da000-b77db000 r-xp 00000000 00:00 0 [vdso]
  • bf819000-bf83a000 rw-p 00000000 00:00 0 [stack]

x86处理器上有两级虚拟内存。一页的大小是4096字节。一个页面目录包含1024个记录,每个记录大小为4个字节。

如何计算虚拟内存表的总体大小?

1 个答案:

答案 0 :(得分:1)

因此,每4096个字节有一个页表项(PTE)。每个1024个PTE的一个页面目录条目。

因此每个条目的数量为:

ptes = (x + 4095) / 4096;
pdes = (ptes + 1023) / 1024

+ 4095和+ 1023是"确保我们至少有一个非零值",以上假定xptes的整数值。

我会留给你把这两个数字加在一起然后再乘以给你字节。

当然,如果您想提高效率,请使用>> 12代替/ 4096>> 10而不是/ 1024 - 这将保证编译器不会实际上执行除法运算。

当我们有多个内存范围时,每个"大块"需要一个PDE。 (1024 x 4096字节,所以即使是4MB范围也会有PDE),然后是一个甚至4K区域的PTE。

所以从你的例子来看:     08048000-08053000 r-xp 00000000 08:03 18877 / usr / bin / cat 没有记忆。保留。

08053000-08054000 r--p 0000a000 08:03 18877 /usr/bin/cat

1 PDE,10 PTE(0xa000 = 10 * 4096字节)

08054000-08055000 rw-p 0000b000 08:03 18877 /usr/bin/cat

0 PDE,1 PTE(0xb000 - 0xa000 = 0x1000 = 4096字节)

091e3000-09204000 rw-p 00000000 00:00 0 [heap]

没有记忆,保留。     4f2d0000-4f2ef000 r-xp 00000000 08:03 1857 /usr/lib/ld-2.15.so 没有记忆,保留

4f2ef000-4f2f0000 r--p 0001e000 08:03 1857 /usr/lib/ld-2.15.so

1个PDE,1个PTE(0xf0000 - 0xef000 = 4096个字节)

4f2f0000-4f2f1000 rw-p 0001f000 08:03 1857 /usr/lib/ld-2.15.so

0 PDE,1 PTE

4f2f7000-4f4a2000 r-xp 00000000 08:03 1858 /usr/lib/libc-2.15.so

无记忆,保留范围

4f4a2000-4f4a3000 ---p 001ab000 08:03 1858 /usr/lib/libc-2.15.so

0 PDE,1 PTE

4f4a3000-4f4a5000 r--p 001ab000 08:03 1858 /usr/lib/libc-2.15.so

0 PDE,2 PTE(0xa5000 - 0xa3000 = 2000)

4f4a5000-4f4a6000 rw-p 001ad000 08:03 1858 /usr/lib/libc-2.15.so

0 PDE,1 PTE

4f4a6000-4f4a9000 rw-p 00000000 00:00 0
b75c0000-b77c0000 r--p 00000000 08:03 57661 /usr/lib/locale/locale-archive
b77c0000-b77c1000 rw-p 00000000 00:00 0
b77d9000-b77da000 rw-p 00000000 00:00 0
b77da000-b77db000 r-xp 00000000 00:00 0 [vdso]
bf819000-bf83a000 rw-p 00000000 00:00 0 [stack]

所以,我认为总的来说,这个特定的可执行文件有2个PDE条目和18个PTE。我可能已经计算了一些错误,但原则上说你是如何为这个特定的例子做的(这似乎是通过加载的一部分,因为它没有使用任何堆栈或堆,这对于一个完全运行的程序来说是不太可能的 - 这可能是在程序实际完全运行之前收集了统计数据,或者其他一些程序)