有没有办法告诉Linux它不应该将特定进程的内存换成磁盘?
它是一个Java应用程序,所以理想情况下我希望能够从命令行执行此操作。
我知道你可以将全局swappiness设置为0,但这是明智的吗?
答案 0 :(得分:25)
您可以通过Linux下的mlockall(2)系统调用执行此操作;这将适用于整个过程,但请阅读您需要传递的参数。
你真的需要把整个东西拉进核心吗?如果它是一个java应用程序,你可能会将整个JVM锁定在内核中。我不知道这样做的命令行方法,但你可以编写一个简单的程序来调用fork
,调用mlockall
,然后调用exec
。
您还可以查看madvise(2)中的某个访问模式通知是否符合您的需求。如果适用于您,建议VM子系统有关更好的分页策略可能会更好。
请注意,很久以前现在在SunOS下,有一种类似于madvise的机制叫vadvise(2)。
答案 1 :(得分:14)
如果您希望更改流程的swappiness,请将其添加到cgroup并设置该cgroup的值:
https://unix.stackexchange.com/questions/10214/per-process-swapiness-for-linux#10227
答案 2 :(得分:2)
您可以通过mlock系列调用来执行此操作。但是,我不确定你是否可以为不同的过程做这件事。
答案 3 :(得分:2)
作为超级用户,您可以将其“优秀”到最高优先级-20,并希望这足以防止它被换出。通常是。正数降低了调度优先级。普通用户不能向上(负面编号)
答案 4 :(得分:2)
存在一类您永远不希望它们交换的应用程序。一个这样的类是数据库。数据库将使用内存作为其磁盘区域的缓存和缓冲区,并且完全没有意义将这些内容交换掉。特定存储器可以保存一些一周不需要的相关数据,直到客户要求它的一天。没有缓存/交换,数据库只会在磁盘上找到相关记录,这将非常快;但是通过交换,您的服务可能会突然花费很长时间来回应。
mysqld
包含使用操作系统/系统调用memlock
的代码。在Linux上,由于至少2.6.9,此系统调用将适用于具有CAP_IPC_LOCK
功能[1]的非root进程。使用memlock()
时,该进程仍必须在LimitMEMLOCK
限制的范围内工作。 [2]。关于systemd
的一些(好的)好处是,您可以授予mysqld
进程这些功能,而无需特殊程序。如果还可以使用ulimit
设置rlimits。这是override
的{{1}}文件,它执行必要的步骤,包括您可能需要的一些进程,例如数据库:
mysqld
注意标准社区mysql目前附带[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
,并在Type=forking
行的服务选项中添加--daemonize
。这固有地不如上述方法稳定。
更新我对这个解决方案并不是百分之百满意。经过几天的运行后,我注意到这个过程仍然有大量的交换!检查ExecStart
,我注意到以下内容:
/proc/XXXX/smaps
选项已损坏。在这种情况下,它并不重要,因为MySQL无法memlock堆栈。 答案 5 :(得分:1)
除非在极不寻常的情况下,提出这个问题意味着你做错了(tm)。
说真的,如果Linux想要交换并且你试图将你的进程留在内存中,那么你就会对操作系统提出不合理的要求。如果您的应用程序非常重要,那么1)购买更多内存,2)从机器中删除其他应用程序/守护进程,或将机器专用于您的应用程序,和/或3)投资一个非常快的磁盘子系统。这些步骤适用于重要的应用程序。如果你无法证明它们的合理性,那么你可能无法证明布线记忆和使其他过程匮乏的合理性。
答案 6 :(得分:1)
你为什么要这样做?
如果您正在尝试提高此应用的性能,那么您可能走错了路。操作系统将换出一个进程来增加磁盘缓存的内存 - 即使有空闲内存,内核最了解(最好是编写调度程序的samrt伙伴最了解)。
如果你有一个需要响应的进程(它在未使用的情况下被替换掉而你需要它快速重启)那么高优先级,mlock或使用实时内核可能有所帮助。