限制用于mmap的缓存缓冲区大小。

11

我有一个数据结构,希望重新设计以进行按需分页。 mmap 似乎是一种运行一些初始实验的简单方法。不过,我想限制 mmap 使用的缓冲区缓存量。机器有足够的内存将整个数据结构分页到缓存中,但出于测试原因(以及某些生产原因),我不想允许它这样做。

是否有一种方法可以限制 mmap 使用的缓冲区缓存量?

或者,一种类似的 mmap 替代方案,可以实现类似的功能并仍然限制内存使用也可以。


2
缓冲区高速缓存由内核自动维护得非常好。它本身不会导致内存错误。你为什么想要自己控制它呢? - fukanchik
@fukanchik 因为我的环境限制,我必须准确知道我的进程将使用多少内存,并将其限制在该范围内。此外,我有一台拥有100GB内存的机器,但我想测试软件时仿佛这台机器只有1GB内存。 - JaredC
我认为你最好不要在应用程序内部处理此问题,而是在操作系统层面上处理。以下是一个很好的起点: https://unix.stackexchange.com/questions/44985/limit-memory-usage-for-a-single-linux-process - user4442671
@fukanchik length 参数控制虚拟映射的大小,而不是在缓存 mmap 内容时使用的物理内存量。 - JaredC
1
@JaredC 我认为在大多数现代操作系统上,不可能限制进程的物理内存使用。如果系统认为这是最好的,它可以自由地向它们分配RAM,而你几乎无法阻止它。你可能别无选择,只能在某种类型的虚拟机或容器中运行。即使如此,你也无法控制系统分配给你的VM管理器的RAM。 - David Schwartz
显示剩余2条评论
4个回答

5
据我所知,这是不可能的。内存映射由操作系统控制。内核会决定如何以最佳方式使用可用内存,但它会全面考虑系统。我不知道是否支持进程级别的缓存配额(至少在Linux或BSD中我没有看到此类API)。
madvise 可以给内核提供提示,但它不支持限制一个进程使用的缓存。您可以给它一些提示,如 MADV_DONTNEED,这将减少其他应用程序缓存的压力,但我认为它会带来更多的伤害而不是好处,因为它很可能使缓存效率降低,从而导致总体上更多的IO负载。
我只看到两个选择。一个是在操作系统层面上解决问题,另一个是在应用程序层面上解决问题。
在操作系统层面上,我看到两个选项:
  1. 您可以运行虚拟机,但最有可能这不是您想要的。我也认为它不会改善整体系统性能。尽管如此,至少它是定义内存消耗上限的一种方式。
  2. Docker 是我想到的另一个想法,也在操作系统层面上运行,但据我所知,它不支持定义缓存配额。我认为这不会起作用。
那只留下了一个选择,即在应用程序层面上解决问题。您可以使用显式文件系统操作而不是内存映射文件。如果您需要完全控制缓冲区,我认为这是唯一实际的选择。它比内存映射更费力,也不能保证表现更好。
如果您想继续使用内存映射,则还可以仅将文件的部分映射到内存中,并在超过内存配额时取消映射其他部分。它也具有与显式文件IO操作相同的问题(更多的实现工作和非平凡的调整以找到良好的缓存策略)。
话虽如此,您可能会质疑限制缓存内存使用的要求。我预计内核会很好地分配内存资源。至少,它可能会比我概述的解决方案更好。(显式文件IO加上内部缓存可能很快,但实现和调整都不容易。这里是权衡的比较:mmap() vs. reading blocks。)

在测试期间,您可以使用ionice -c 3nice -n 20运行应用程序,以在一定程度上减少对其他生产应用程序的影响。 还有一个名为nocache的工具。我从未使用过它,但在阅读其文档时,它似乎与您的问题有关。


2

通过使用mmap()Linux Control Groups(更一般地,这里这里),可能可以实现此目标。一旦安装,您就可以对进程使用的物理内存等内容设置任意限制。例如,在这里,我们将物理内存限制为128兆字节,交换内存限制为256兆字节:

cgcreate -g memory:/limitMemory
echo $(( 128 * 1024 * 1024 )) > /sys/fs/cgroup/memory/limitMemory/memory.limit_in_bytes
echo $(( 256 * 1024 * 1024 )) > /sys/fs/cgroup/memory/limitMemory/memory.memsw.limit_in_bytes

0
我会选择每次只映射文件的部分,这样您就可以完全控制使用多少内存。

那样做不起作用,因为缓存在取消映射文件后仍然存在。 - Juergen

0

你可以使用IPC共享内存段,你将成为您的内存段的主人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接