【问题标题】:Memory table-size内存表大小
【发布时间】:2015-10-26 22:33:29
【问题描述】:

我有文件,描述进程的 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 [堆]
  • 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 [堆栈]

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

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

【问题讨论】:

  • 你有没有试过自己做这个计算?
  • @MatsPetersson 我想这样做,但我不明白该怎么做。我想我可以计算非零偏移量(表中的 3 列)并乘以 4096,所以我得到了以字节为单位的大小。但我不确定,如果它是正确的方式。你能解释一下,我该怎么做?
  • 所以,我的问题基本上是“尝试进行计算并解释你做了什么” - 这不完全是火箭科学,而是非常基本的计算。
  • @MatsPetersson 我向您解释,我不完全理解,我做得对。我向您描述了我使用的方法,并想知道它是否正确。你能回答我,如果它是正确的,或者解释如果它不是。
  • 将上表中的尺寸乘以4096显然是不对的。

标签: c++ memory x86


【解决方案1】:

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

所以每个条目的数量是:

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

+4095 和 +1023 是为了“确保我们至少有一个用于任何非零值”,上面假设 xptes 的整数值。

我会让你把这两个数字相加并相乘得到字节。

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

当我们有多个内存范围时,您需要为每个“大块”(1024 x 4096 字节,因此即使是 4MB 范围也会有一个 PDE)使用一个 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。我可能算错了,但原则上这就是这个特定示例的方式(这似乎是加载的一部分,因为它没有使用任何堆栈或堆,这对于完全运行的程序来说不太可能 -这可能是在程序真正完全运行之前收集的统计信息,或者类似的)

【讨论】:

  • 我可以计算进程的映射虚拟内存的大小。对于上表,它是 4345856 字节,所以 ptes 的数量 = 1061。所以 pdes = 2。然后我必须做什么?
  • 我无法理解,为什么我的示例中的表大小为 28672。我进行下一个计算:4345856 - 表的映射虚拟内存大小,因此 4345856/4096 = 1061 页,1061 / 1024 = 2第二级的页面目录,所以 2 个目录和一个链接到它们的目录,所以 3 * 1024 * 4 = 12288。我添加了有问题的完整表格。
  • 所以对于那个例子,你需要 (1061 + 2) * 4 字节。懒得拿出计算器。
  • 但是,请参阅我对页表大小计算的编辑。我不知道 28672 是从哪里来的。
猜你喜欢
  • 2018-07-27
  • 2011-11-07
  • 1970-01-01
  • 2015-11-30
  • 1970-01-01
  • 2020-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多