2009-02-23 80 views
36

有没有办法告诉Linux不应该将特定进程的内存换出到磁盘上?我可以告诉Linux不要换出特定进程的内存吗?

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

我知道你可以将全局swappiness设置为0,但这是明智的吗?

+0

如果您在应用程序上执行了“chmod + S”,Unix会用来表示“粘性位”,但我认为这不再适用。 – 2009-02-23 16:00:39

+1

对不起,我的意思是“chmod + t”,但我只是看着,Linux忽略了粘性位。 – 2009-02-23 16:02:16

+0

http://blogs.msdn.com/b/oldnewthing/archive/2005/06/07/426294.aspx – Hello71 2011-02-09 03:08:32

回答

22

您可以通过Linux下的mlockall(2)系统调用来完成此操作;这将适用于整个过程,但请阅读您需要传递的论点。

你是否真的需要将所有东西都拉进内核?如果它是一个Java应用程序,那么您可能会锁定整个JVM内核。我不知道这样做的命令行方法,但是你可以写一个简单的程序来调用fork,调用mlockall,然后exec

您也可以查看madvise(2)中的某个访问模式通知是否符合您的需求。向虚拟机子系统提供更好的分页策略可能会更好,如果它适用于您。

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

2

你可以通过mlock系列调用系列来实现。但是,我不确定是否可以为不同的流程做到这一点。

2

作为超级用户,您可以“高兴”到最高优先级-20,并希望这足以防止它被换出。它通常是。正数降低调度优先级。普通用户无法向上(负号)

2

除极端特殊情况外,询问此问题意味着您做错了(tm)。

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

1

你为什么要这样做?
如果你想提高这个应用程序的性能,那么你可能是在错误的轨道上。操作系统将换出一个进程来增加磁盘缓存的内存 - 即使有空闲的内存,内核也知道最好(编写调度器的samrt家伙最了解它)。
如果你有一个需要响应的进程(它在不使用时换出,而你需要快速重启),那么把它设置为高优先级,mlock或使用实时内核可能会有所帮助。

2

存在着一类的应用程序中,你永远不希望他们交换。一个这样的类是一个数据库。数据库将使用内存作为其磁盘区域的缓存和缓冲区,并且这绝对没有意义,因为这些都是可以交换的。特定的内存可能包含一些一周内不需要的相关数据,直到客户请求它的一天。如果没有缓存/交换,数据库会简单地在磁盘上找到相关记录,这很快;但随着交换,您的服务可能突然需要很长时间才能做出回应。

mysqld包括使用OS /系统调用memlock的代码。在Linux上,由于至少2.6.9,此系统调用将适用于具有CAP_IPC_LOCK功能[1]的非根进程。当使用memlock()时,该过程必须仍在LimitMEMLOCK限制的范围内工作。 [2]。关于systemd的(少数)好事之一是,您可以授予mysqld进程这些功能,而不需要特殊的程序。如果还可以按照您的预期设定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,并增加了--daemonizeExecStart行的服务选项中。这本质上不如上述方法稳定。

UPDATE我对此解决方案并不满意。经过几天的运行,我注意到这个过程仍然有大量的交换!检查/proc/XXXX/smaps,我注意到以下内容:

  • 交换的最大贡献者来自堆栈段! 437 MB并波动。这表现出明显的性能问题。它还表示基于堆栈的内存泄漏。
  • 还有零锁定页面。这表示MySQL(或Linux)中的memlock选项已损坏。在这种情况下,这并不重要,因为MySQL不能使用memlock堆栈。
相关问题