【发布时间】:2010-09-24 16:16:06
【问题描述】:
我在多个线程中描述了一个问题,该问题涉及 Linux 下的内存映射和不断增长的内存消耗。
当我在 Linux 或 MacOS X 下打开一个 1GB 的文件并将其映射到内存时使用
me.data_begin = mmap(NULL, capacity(me), prot, MAP_SHARED, me.file.handle, 0);
并顺序读取映射内存,我的程序使用了越来越多的物理内存,尽管我使用了 posix_madvise(甚至在读取过程中多次调用它):
posix_madvise(me.data_begin, capacity(me), MMAP_SEQUENTIAL);
没有成功。 :-(
我试过了:
- 不同的标志 MMAP_RANDOM、MMAP_DONTNEED、MMAP_NORMAL 没有成功
- posix_fadvise(me.file.handle, 0, capacity(me), POSIX_FADV_DONTNEED) 在调用 mmap 前后 -> 不成功
它在 Mac OS X 下工作 !!!当我结合
posix_madvise(.. MMAP_SEQUENTIAL)
和
msync(me.data_begin, capacity(me), MS_INVALIDATE).
常驻内存低于16M(我在16mio步骤后定期调用msync)。
但在 Linux 下没有任何效果。有人对我在 Linux 下的问题有想法或成功案例吗?
干杯, 大卫
【问题讨论】:
-
它可能相关也可能不相关,但了解以下信息应该很有用:您使用的是 32 位还是 64 位系统?你知道你不应该在 32 位系统中映射 1GB 吗? (即使您使用的是 64 位系统,您也可能会担心可移植性)。
-
所有系统都是 64 位(带有 64 位文件指针和偏移量),我可以成功映射 40GB 文件。为了重现性,我只是将问题归结为 1GB。
-
@Sven。在某些情况下使用内存映射是不可避免的,例如当库调用需要内存区域而不是文件时。所以你的建议没有帮助,也没有回答问题。至于答案,显然在 Linux MMAP_SEQUENTIAL 上几乎是broken。预读部分有效,页面回收部分无效。向 Linux 建议事实上这些页面是很好的候选者的唯一方法是取消映射该区域(并再次映射它)。