我可以告诉Linux不要换出特定进程的内存吗?
有没有办法告诉Linux不应该把特定进程的内存换成磁盘?
它是一个Java应用程序,所以理想情况下,我希望能够从命令行执行此操作。
我知道你可以把全球swappiness设置为0,但这是明智的吗?
你可以通过Linux下的mlockall(2)系统调用来做到这一点。 这将在整个过程中发挥作用,但请阅读您需要传递的论点。
你真的需要把整个事情放在核心? 如果这是一个Java应用程序,你可能会locking整个JVM内核。 我不知道这样做的命令行方法,但你可以写一个简单的程序来调用fork
,调用mlockall
,然后exec
。
你也可以看看madvise(2)中的一个访问模式通知是否符合你的需求。 为虚拟机子系统提供一个更好的分页策略的build议可能会更好,如果它适用于你。
请注意,很久以前在SunOS下,有一种类似于madvise的机制叫做vadvise(2) 。
如果您希望更改进程的swappiness,请将其添加到cgroup并设置该cgroup的值:
https://unix.stackexchange.com/questions/10214/per-process-swapiness-for-linux#10227
你可以通过系统调用的mlock系列来做到这一点。 但是,我不确定,如果你可以做一个不同的过程。
作为超级用户,您可以“高兴”到最高优先级-20,并希望这足以防止被换出。 通常是这样。 正数较低的调度优先级。 普通用户无法向上(负数)。
除了极端不寻常的情况,问这个问题意味着你做错了(tm)。
说真的,如果Linux想要交换,而且你试图在内存中保留你的进程,那么你对操作系统提出了一个不合理的要求。 如果你的应用程序是那么重要,那么1)购买更多的内存,2)从机器上删除其他应用程序/守护进程,或专用一台机器到你的应用程序,和/或3)投资于一个非常快的磁盘子系统。 这些步骤对于重要的应用程序是合理的。 如果你不能certificate它们是正确的,那么你可能无法certificate连接内存和挨饿其他进程。
有一类应用程序,你永远不希望他们交换。 一个这样的类是一个数据库。 数据库将使用内存作为他们的磁盘区域的caching和缓冲区,这是绝对没有意义的,这些都是交换。 特定的内存可能会保存一些不需要的相关数据,直到有一天客户要求为止。 如果没有caching/交换,数据库会简单地在磁盘上find相关的logging,这将是相当快的; 但随着交换,你的服务可能会突然花费很长时间来回应。
mysqld
包含使用OS /系统调用memlock
。 在Linux上,由于至less2.6.9,此系统调用将适用于具有CAP_IPC_LOCK
function的非根进程[1] 。 当使用memlock()
,进程必须仍然在LimitMEMLOCK
限制的范围内工作。 [2] 。 关于systemd
的(less数)好事之一是你可以授予mysqld
进程这些能力,而不需要特殊的程序。 如果还可以像使用ulimit
那样设置rlimits。 这里是一个mysqld
的override
文件,它执行必要的步骤,包括一些其他的你可能需要的一个过程,如数据库:
[Service] # Prevent mysql from swapping CapabilityBoundingSet=CAP_IPC_LOCK # Let mysqld lock all memory to core (don't swap) LimitMEMLOCK=-1 # do not kills this process if low on memory OOMScoreAdjust=-900 # Use higher io scheduling IOSchedulingClass=realtime Type=simple ExecStart= ExecStart=/usr/sbin/mysqld --memlock $MYSQLD_OPTS
注意标准社区mysql目前附带Type=forking
并在ExecStart
行的服务选项中添加了--daemonize
。 这本质上不如上述方法稳定。
更新我对此解决scheme并不满意。 经过几天的运行,我注意到这个过程仍然有大量的交换! 检查/proc/XXXX/smaps
,我注意到以下几点:
- 交换的最大贡献者来自堆栈段! 437 MB和波动。 这提出了明显的性能问题。 它也表示基于堆栈的内存泄漏。
- 有零locking页面 。 这表示MySQL(或Linux)中的
memlock
选项已损坏。 在这种情况下,这并不重要,因为MySQL不能使用memlock堆栈。
你为什么要这样做?
如果你正试图提高这个应用程序的性能,那么你可能是在错误的轨道上。 操作系统将换出一个进程来增加磁盘caching的内存 – 即使有空闲的内存,内核也知道最好(编写调度器的samrt家伙知道的最好)。
如果你有一个需要响应的进程(在没有使用的时候换出来,你需要快速重启),那么把它设置为高优先级,mlock或者使用实时内核可能会有帮助。