2

我使用 mmap(只是想了解 mmap 的工作原理)分配 96k 匿名内存,但看起来它将 96k 拆分为 64k 和 32k。但是当分配 960k 时,它只分配一个大小为 960k 的块。solaris 什么时候将 allocate mem 分成几部分?代码:

#define PROT PROT_READ | PROT_WRITE
#define MAP  MAP_ANON  | MAP_PRIVATE
if ((src = mmap(0, 88304, PROT, MAP, -1, 0)) == MAP_FAILED)
    printf("mmap error for input");

if ((src = mmap(0, 983040, PROT, MAP, -1, 0)) == MAP_FAILED)
    printf("mmap error for input");

if ((src = mmap(0, 98304, PROT, MAP, -1, 0)) == MAP_FAILED)
    printf("mmap error for input");

桁架:

mmap(0x00000000, 88304, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0)
    = 0xFFFFFFFF7E900000
mmap(0x00000000, 983040, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0)
    = 0xFFFFFFFF7E800000
mmap(0x00000000, 98304, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0)
    = 0xFFFFFFFF7E700000

地图:

FFFFFFFF7E700000         64     -          -          - rw---    [anon]
    ==> strange is that for 96k, it was broken into 2 part.
FFFFFFFF7E710000         32     -          -          - rw---    [anon]
FFFFFFFF7E800000        960     -          -          - rw---    [anon]
FFFFFFFF7E900000         64     -          -          - rw---    [anon]
FFFFFFFF7E910000         24     -          -          - rw---    [anon]
FFFFFFFF7EA00000         64     -          -          - rw---    [anon]
FFFFFFFF7EA10000         32     -          -          - rw---    [anon]
4

3 回答 3

3

连续的内存,您可以通过地址来判断,(F...700000 + 64K = F...710000)所以我认为您不必担心。我很确定 mmap 需要在您的地址空间中为您提供连续的内存。否则它将毫无用处,因为它只给你一个基地址。对于两个不连续的块,将无法找到第二个块。

所以我想你的问题是:为什么这在 pmap 中显示为两个块?

我的回答是,“如果我知道的话,我会很高兴”。但我可以做出明智的猜测,在早上的这个时候(咖啡前),任何人都可以从我这里得到最好的结果。

我建议这些块之前已分配给另一个(或两个)进程,并已释放回 mmap 内存管理器。我可以看到关于内存管理器如何合并块以生成更大的空闲块的两种可能性:

  • 它会在内存释放后立即执行(不是您的输出显示没有发生的情况)。
  • 它会定期执行它,并且在您请求 96K 块之前它还没有解决;或者
  • 它一点也不麻烦,因为它足够聪明,可以在为你分配块的过程中做到这一点。

我怀疑是后者仅仅是因为内存管理器没有问题给你两个块来满足你的请求,所以它显然是为了处理它而构建的。960K 块可能没有被分段,因为它来自一个更大的块。

请记住,这是猜测(知情,但仍然是猜测)。我已经看到了很多 UNIX 的内部结构(真正的 UNIX,而不是那个新人 :-),但我从来没有需要深入研究 mmap。

于 2009-05-08T02:17:57.273 回答
3

我不记得它的术语(条纹?切片?楔子?啊),但 Solaris 从各种大小的池中分配不同的页面大小。事实证明,这比统一页面大小更有效,因为它更好地使用了内存映射。我相信其中一个尺寸是 32K,另一个是 64K,另一个是 1024K。要获得 96K,您需要 64 和 32,要获得 960,您可以获得 1024K 的大部分。

这个魔法的核心资源是Solaris Internals书。我的,不幸的是,在妈妈的车库里的一个盒子里。

于 2009-05-08T02:35:38.230 回答
0

答案取决于您所说的连续。Solaris 和所有现代 Unix 和类 unix 系统(可能所有现代操作系统)都将物理内存划分为页面,并且“页面”内的内存在物理级别上是连续的。大多数现代系统都有一个硬件 MMU(内存管理单元),它将虚拟地址转换为物理地址。因此 mmap 系统调用将返回一个连续的虚拟地址空间,但该虚拟地址将由 MMU 管理,该 MMU 可能使用多个页面,具体取决于页面的大小和内存映射的大小。

虽然所有虚拟地址都是连续的(在映射内),但“页面”内的地址也将是物理上连续的,但页面和页面之间的转换甚至可能在物理上彼此不接近。

于 2014-01-17T17:24:28.513 回答