![强制使用 FILE 而不是 RAM 的工具](https://linux22.com/image/53142/%E5%BC%BA%E5%88%B6%E4%BD%BF%E7%94%A8%20FILE%20%E8%80%8C%E4%B8%8D%E6%98%AF%20RAM%20%E7%9A%84%E5%B7%A5%E5%85%B7.png)
我想知道为什么没有这样的工具内存2交换,部分类似于 cpulimit 。
例如
有程序daemon.bin。
让我们创建临时交换文件(1 GB):
% dd if=/dev/zero of=tmp.swap bs=1m count=1000
发射:
% cpulimit -l 10 ram2swap -f tmp.swap daemon.bin
daemon.bin 将在文件中分配内存,而不是使用 RAM 或 SWAP tmp.swap
。
性能大幅下降,是的。但这如何灵活。
答案1
不存在这样的工具,因为从单个程序的角度来看它没有任何意义。
可以将 CPU/HDD/RAM/swap 视为资源。操作系统可以以不同的方式在进程、用户、上下文等之间共享这些资源。
在某些特定情况下,告诉操作系统强制执行硬限制是有意义的:
- 不要让该程序使用超过 60% 的内存。
- 如果其他用户需要,请勿允许该用户使用超过 20% 的 CPU 时间。否则允许他使用 100% CPU。
- 不允许该组中的用户使用超过 2 个内核。
- ...
这提供了一个真实的灵活性:根据管理员的意愿并且操作系统遵守,在用户之间共享资源。
为什么手动将程序放入交换区不是一个好主意?
- 您基本上假设您比内核中的启发式方法更好。内核已经自行处理交换空间。如果一个守护进程很长时间没有被激活并且操作系统缺乏RAM,它最终将被放入交换区。
- AFAIK,交换区不可执行:在执行之前,需要将交换区的内容检索到 RAM 中。因此,如果您正在考虑从 RAM 执行第一类程序,从交换中执行第二类程序:立即停止,这是行不通的。
- “是的,但是那个特定的守护进程每月被调用两次。我不需要它在 RAM 中”。如果这是真的,那么如果你缺少 RAM,内核将放入交换区。
- “为什么要等待内存不足呢?”将东西放入和取出交换非常昂贵,尤其是在普通的旧硬盘上。如果您的系统可以将所有内容保存在 RAM 中,那么最好就让它这样做。如果您暂时将某些内容强行放入交换中,您的系统的响应速度将会降低。由于您的其他“第一类”守护进程很可能也应该执行一些 HDD IO,因此这些守护进程也会减慢。当“第二类”守护进程唤醒并需要放入 RAM 时,也会发生同样的情况。
现在,为什么用户不能使用神奇的命令行将程序放入交换区?
- 从用户空间(非内核)的角度来看,尚不清楚应该将什么放入交换中。您的程序链接到
libmylib.so
,是否也应该将其放入交换中?那么呢libc.so
? - 实际上预期的行为是什么?您希望守护进程直接放入交换区吗?但它必须做一些初始化工作,不是吗?然后,一旦您加载它,它就会返回到 RAM。
- 您如何继续知道守护进程不再使用并且可以再次安全地放入交换中?
- 应该直接送回交换区还是应该稍等一下?否则,在每次睡眠时,您的守护进程将被放入交换区,并且在每次唤醒时,它将被放回 RAM 中。例如,如果您的守护程序更新您的计算机时钟,请准备好进行数小时的交换。
- ...
简而言之,您需要内核来处理它,而这正是它所做的。对于大多数需求,调整交换性足以获得响应系统。
现在,如果你真的想
(来源:Freakoutnation.com) ,内核通过使用cgroups
.您可以通过在 中为您的守护进程设置 max mem 和 max mem+swap 来获得您认为想要的内容cgroups
。您可以通过设置每个程序的交换性来获得更合理的结果。但无论哪种方式,这都不是一个好主意,我不会走得更远这作为解释。
答案2
您所描述的情况是这样的:有一个功能可以限制进程使用的 RAM 量(RAM,而不是虚拟内存)。该RLIMIT_RSS
限制设置程序驻留集大小的上限,即该进程驻留在内存中的内存部分(而不是换出)。然而,它并没有在 Linux 上实现。
RLIMIT_RSS
存在于一些旧的 Unix 系统中(仅限 BSD?),但已从许多现代系统中删除。在Linux,它只存在于2.4系列上(甚至没有完全工作)。在 Solaris 上是掉落在遥远的过去的某个时刻(当Solaris SunOS 从 BSD 切换到 System V 时?)。自由BSD好像还有。
不知道为什么RLIMIT_RSS
被删了艾伦·考克斯2006年曾说过这样一句话:
Linux 的原始 mm 没有强制执行它,因为它没有任何方法来跟踪 RSS,而计算量并不昂贵。当前的 mm 可能能够实现 RSS 限制,尽管如果用户设置较低的 RSS 限制并导致大量交换抖动,这会产生什么影响仍然存在疑问。
如果您能找到一种有效实施的方法,那么就去做吧。
从那时起,这个话题已经出现了好几次,但据我所知,Linux 内核还没有接受任何补丁。
对进程的物理内存使用实施限制的原因之一是很难定义进程正在使用多少物理内存。好吧,统计一下它的栈和堆(没有换出的部分)。内存映射文件怎么样?要测量进程的物理内存使用情况,您必须计算它映射的文件使用的缓存。共享库和其他共享映射怎么样?如果它们被单个进程使用,那么显然它们应该被计算在内——但是当它们被多个进程使用时,很难知道哪个进程正在使用哪个部分。
限制单个进程的物理内存使用没有多大意义。鉴于资源限制是继承的,每个孩子将被允许使用尽可能多的物理内存。允许对一组进程的物理内存进行限制更有意义。 Linux 内置了这个功能cgroups,一个部分虚拟化系统,其中进程及其后代在容器中运行,容器可以拥有自己的文件系统根、自己的网络控制器、自己的资源限制等。cgroup的内存使用情况可以通过memory.limit_in_bytes
参数进行限制(memory.memsw.limit_in_bytes
控制 RAM 和交换区的使用)。文档警告说,组之间共享的页面是以某种任意的方式分配的(“共享页面是根据第一次触摸方法进行计算的。首先触摸页面的 cgroup 会计算该页面。”)。那里可能是其他方式其中限制没有严格执行。
您要求的另一部分是为进程提供专用的交换文件。这需要内核相当复杂。请记住,页面可以共享;如果两个进程分配了不同的交换空间,则使用哪个交换文件?另一方面,该功能可以从进程端相当容易地实现:将文件映射到内存。对于共享页面,仍然有一个文件。另一个好处是,进程的不同区域可以使用不同的“交换空间”。