47

有没有办法告诉 Linux 它不应该将特定进程的内存交换到磁盘?

它是一个 Java 应用程序,所以理想情况下我希望有一种方法可以从命令行执行此操作。

我知道您可以将 global swappiness 设置为 0,但这明智吗?

4

7 回答 7

25

你可以通过 Linux 下的mlockall(2)系统调用来做到这一点;这将适用于整个过程,但请阅读您需要通过的参数。

你真的需要把整个事情都拉到核心吗?如果它是一个 java 应用程序,您可能会将整个 JVM 锁定在内核中。我不知道执行此操作的命令行方法,但是您可以编写一个简单的程序来调用fork,调用mlockall,然后exec

您还可以查看madvise(2)中的访问模式通知之一是否满足您的需求。如果它适用于您,向 VM 子系统建议更好的分页策略可能会更好。

请注意,很久以前现在在 SunOS 下,有一种类似于 madvise 的机制,称为vadvise(2)

于 2009-02-23T16:21:30.453 回答
15

如果您希望更改进程的交换性,请将其添加到 cgroup 并设置该 cgroup 的值:

https://unix.stackexchange.com/questions/10214/per-process-swapiness-for-linux#10227

于 2012-09-10T10:35:32.113 回答
2

您可以通过mlock系列系统调用来做到这一点。但是,我不确定您是否可以针对不同的流程执行此操作。

于 2009-02-23T15:58:56.357 回答
2

作为超级用户,您可以将其“优化”到最高优先级 -20,并希望这足以防止它被换出。通常是这样。正数降低调度优先级。普通用户不能向上友好(负数)

于 2009-02-23T16:56:07.000 回答
2

存在一类应用程序,您永远不希望它们交换。一个这样的类是数据库。数据库将使用内存作为其磁盘区域的缓存和缓冲区,并且将它们放入交换绝对没有任何意义。特定的内存可能会保存一些一周内不需要的相关数据,直到有一天客户要求它。如果没有缓存/交换,数据库将简单地在磁盘上找到相关记录,这将是相当快的;但是通过交换,您的服务可能突然需要很长时间才能响应。

mysqld包括使用操作系统/系统调用的代码memlock。在 Linux 上,至少从 2.6.9 开始,此系统调用将适用于具有CAP_IPC_LOCK能力[1]的非 root 进程。使用memlock()时,进程必须仍然在LimitMEMLOCK限制范围内工作。[2]。(少数)好处之一systemd是您可以授予mysqld进程这些功能,而无需特殊程序。If 还可以按照您的预期设置 rlimits ulimit。这是一个override用于mysqld执行必要步骤的文件,其中包括您可能需要的一些其他步骤,例如数据库:

[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 并添加--daemonize选项到服务就ExecStart行了。这本质上不如上述方法稳定。

更新我对这个解决方案不是 100% 满意。经过几天的运行,我注意到这个过程仍然有大量的交换!检查/proc/XXXX/smaps,我注意到以下几点:

  • 交换的最大贡献者来自堆栈段!437 MB和波动。这带来了明显的性能问题。它还表示基于堆栈的内存泄漏。
  • 锁定页面为零。这表明memlockMySQL(或 Linux)中的选项已损坏。在这种情况下,这并不重要,因为 MySQL 不能 memlock 堆栈。
于 2016-06-15T11:41:22.233 回答
1

除非在极不寻常的情况下,问这个问题意味着你做错了(tm)。

说真的,如果 Linux 想要交换并且您试图将进程保留在内存中,那么您对操作系统提出了不合理的要求。如果您的应用程序如此重要,那么 1) 购买更多内存,2) 从机器中删除其他应用程序/守护程序,或将机器专用于您的应用程序,和/或 3) 投资一个非常快速的磁盘子系统。这些步骤对于重要的应用程序是合理的。如果你不能证明它们是合理的,那么你可能也不能证明连接内存和饿死其他进程是合理的。

于 2009-02-23T17:11:45.497 回答
1

你为什么要这样做?
如果您试图提高此应用程序的性能,那么您可能走错了路。操作系统将换出一个进程以增加磁盘缓存的内存 - 即使有可用的 RAM,内核也最清楚(实际上编写调度程序的 samrt 人最清楚)。
如果您有一个需要响应的进程(它在不使用时被换出并且您需要它快速重新启动),那么将其设置为高优先级、mlock 或使用实时内核可能会有所帮助。

于 2009-02-23T17:34:27.423 回答