我能告诉Linux不要交换特定的进程吗';记忆?

我能告诉Linux不要交换特定的进程吗';记忆?,linux,swap,Linux,Swap,有没有办法告诉Linux它不应该将特定进程的内存交换到磁盘上 这是一个Java应用程序,所以理想情况下,我希望能从命令行实现这一点 我知道您可以将全局交换设置为0,但这明智吗?您可以通过一系列系统调用来实现这一点。但是,我不确定您是否可以为不同的进程执行此操作。您可以通过Linux下的系统调用执行此操作;这将适用于整个过程,但请务必阅读您需要传递的论点 你真的需要把整个事情都拉进去吗?如果它是java应用程序,您可能会将整个JVM锁定在内核中。我不知道有什么命令行方法可以做到这一点,但您可以编写

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

这是一个Java应用程序,所以理想情况下,我希望能从命令行实现这一点

我知道您可以将全局交换设置为0,但这明智吗?

您可以通过一系列系统调用来实现这一点。但是,我不确定您是否可以为不同的进程执行此操作。

您可以通过Linux下的系统调用执行此操作;这将适用于整个过程,但请务必阅读您需要传递的论点

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

您还可以查看中的某个访问模式通知是否满足您的需要。如果适用于您,建议VM子系统使用更好的分页策略可能效果更好


请注意,很久以前,在SunOS下,有一种类似于madvise的机制称为。

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

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


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

为什么要这样做?
如果您试图提高此应用程序的性能,那么您可能走错了方向。操作系统将交换一个进程以增加磁盘缓存的内存-即使有空闲的RAM,内核也最清楚(实际上编写调度器的samrt人员最清楚)。

如果您有一个需要响应的进程(它在未使用时被调出,您需要它快速重新启动),那么将其设置为高优先级、mlock或使用实时内核可能会有所帮助。

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


存在一类应用程序,您永远不希望在其中进行交换。其中一个类是数据库。数据库将使用内存作为其磁盘区域的缓存和缓冲区,而将这些缓存和缓冲区进行交换是毫无意义的。特定内存可能保存一些相关数据,这些数据在一周内都不需要,直到有一天客户机请求时才需要。如果没有缓存/交换,数据库只需在磁盘上查找相关记录,这将非常快;但是,通过交换,您的服务可能突然需要很长时间才能响应

mysqld
包括使用操作系统/系统调用的代码
memlock
。在Linux上,由于至少2.6.9版本,此系统调用将适用于具有
CAP\u IPC\u LOCK
功能的非根进程。使用
memlock()
时,进程必须仍在
LimitMEMLOCK
限制的范围内工作。
systemd
的一个(少数)好处是,您可以授予
mysqld
处理这些功能,而无需特殊程序。If还可以使用
ulimit
设置RLimit。下面是一个用于
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
。与上述方法相比,该方法本质上不太稳定

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

  • 交换的最大贡献者来自堆栈段437MB且波动。这会带来明显的性能问题。它还表示基于堆栈的内存泄漏
  • 零锁定页面。这表示MySQL(或Linux)中的
    memlock
    选项已损坏。在这种情况下,这无关紧要,因为MySQL不能锁定堆栈
如果你在一个应用程序上使用了“chmod+S”,Unix通常会尊重“粘性部分”,但我认为这已经不起作用了。对不起,我是说“chmod+t”,但我只是查看了一下,Linux忽略了粘性部分。@Hello71:这是一篇不错的博客文章,但它讨论了Microsoft Windows。我不知道它是如何应用于这个问题的,除了最一般的操作系统原则。看起来和我很相似:-我会小心有多少系统内存被锁定。如果你不小心的话,我怀疑你可能会通过破坏系统来破坏它。如果它与密码学有关,那么想保留在内存中是完全合理的。例如,gnome钥匙圈需要采取相当多的步骤来保持自身的重要部分不被交换。(除此之外,还有合理的观察。)保罗,说得好。我确实觉得这是一个不寻常的情况。这在银行业和支付卡行业是很常见的,有着很强的加密要求。那么不使用太多内存的UI相关流程呢?例如桌面管理器的面板之类的东西?用户界面的东西应该是r