如何将所有正在运行的应用程序从交换空间重新加载到RAM?


20

如果我的桌面内存不足并交换了很多内存,那么我会释放或杀死浪费RAM的应用程序。但是,在那之后,我所有的桌面/应用程序都已被交换并且非常慢,您知道一种“取消交换”(从交换空间重新加载到RAM中)我的桌面/应用程序的方法吗?


与其使用swapon/ 来取消整个系统的交换swapoff(如当前接受的答案所建议的那样),您可能不希望通过转储其进程存储器(强制进行交换)来交换显示管理器及其所有子级。另请参见 stackoverflow上的“如何强制换出的zsh进程换入?”
zrajm 2013年

Answers:


16

如果确实有足够的可用RAM,则可以使用以下顺序(以root用户身份):

$ swapoff -a
$ swapon -a

(以强制所有应用程序的显式交换)

(假设您使用的是Linux)


即使您不使用IIRC,它也会移动尽可能多的数据。虽然它可能会损坏缓存和合作。有时很有用。
Maciej Piechotka,2011年

18

以下快速且肮脏的python脚本将进程的内存转储到stdout。这具有加载任何换出的页面或映射文件的副作用。将其称为cat_proc_mem 123 456 789参数是进程ID的位置。

该脚本完全特定于Linux。它可能适用于其他具有类似/proc结构的系统(Solaris?),但是不必在* BSD上运行它。即使是在Linux上,您可能需要更改的定义c_pid_t和值PTRACE_ATTACHPTRACE_DETACH。这是一个原则证明脚本,并不意味着它是良好编程实践的示例。使用风险自负。

Linux使进程的内存可用/proc/$pid/mem。仅某些地址范围是可读的。通过从文本文件中读取内存映射信息可以找到这些范围/proc/$pid/maps/proc/$pid/mem拥有读取权限的所有进程都无法读取该伪文件:阅读器进程必须已调用ptrace(PTRACE_ATTACH, $pid)

#!/usr/bin/env python
import ctypes, re, sys

## Partial interface to ptrace(2), only for PTRACE_ATTACH and PTRACE_DETACH.
c_ptrace = ctypes.CDLL("libc.so.6").ptrace
c_pid_t = ctypes.c_int32 # This assumes pid_t is int32_t
c_ptrace.argtypes = [ctypes.c_int, c_pid_t, ctypes.c_void_p, ctypes.c_void_p]
def ptrace(attach, pid):
    op = ctypes.c_int(16 if attach else 17) #PTRACE_ATTACH or PTRACE_DETACH
    c_pid = c_pid_t(pid)
    null = ctypes.c_void_p()
    err = c_ptrace(op, c_pid, null, null)
    if err != 0: raise SysError, 'ptrace', err

## Parse a line in /proc/$pid/maps. Return the boundaries of the chunk
## the read permission character.
def maps_line_range(line):
    m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line)
    return [int(m.group(1), 16), int(m.group(2), 16), m.group(3)]

## Dump the readable chunks of memory mapped by a process
def cat_proc_mem(pid):
    ## Apparently we need to ptrace(PTRACE_ATTACH, $pid) to read /proc/$pid/mem
    ptrace(True, int(pid))
    ## Read the memory maps to see what address ranges are readable
    maps_file = open("/proc/" + pid + "/maps", 'r')
    ranges = map(maps_line_range, maps_file.readlines())
    maps_file.close()
    ## Read the readable mapped ranges
    mem_file = open("/proc/" + pid + "/mem", 'r', 0)
    for r in ranges:
        if r[2] == 'r':
            mem_file.seek(r[0])
            chunk = mem_file.read(r[1] - r[0])
            print chunk,
    mem_file.close()
    ## Cleanup
    ptrace(False, int(pid))

if __name__ == "__main__":
    for pid in sys.argv[1:]:
        cat_proc_mem(pid)

另请参阅上的更多信息/proc/$pid/mem

unswap () {
  cat_proc_mem "$@" >/dev/null
}

2
这是我在堆栈交换上见过的最酷的事情之一。发布此荣誉!有很多好的掘金可以从中受益。
2015年

毫无疑问,我无法使该脚本正常工作。使用python 2时,显示值r [0]太大的错误。在python 3上(解决了一些小问题之后),我得到OSError:[Errno 5]在块= mem_file.read(r [1]-r [0])处的输入/输出错误,并且我在其上使用的程序都挂在了两者上案件。
barteks2x

@ Barteks2x对不起,我现在没有时间对此脚本进行防错。它对我确实有效,至少在没有太多安全限制的机器上(该技术使用一些在强化设置中禁用的调试接口)。跟踪该程序时将其挂起,向其发送SIGCONT(kill -CONT 1234其中1234是PID)以恢复​​该程序。
吉尔(Gilles)'“ SO-别再邪恶了”

@ Barteks2x:我在这里添加了一些错误检查。这使脚本甚至可以处理/ dev / dri / card0中的IOErrors和[vsyscall]中的OverflowErrors。(它还会打印出问题区域)。
hackerb9

6

仅出于完整性考虑,GDB可以转储过程映像。我没有检查它unswaps它,但它具有---有没有其他的方式来读取整个进程内存:
gdb -p $mypid
后跟
(gdb) gcore /tmp/myprocess-core
Saved corefile /tmp/myprocess-core


3
gcore $pid也可以在gdb之外使用(作为一个小的包装脚本)
Tobu 2014年

gcore无法写入/ dev / null,如果您试图将进程强制回内存,这就是您想要的。但是,您可以像这样通过单个命令来做到这一点: gdb --batch -p $pid -ex "gcore /dev/null" 2>/dev/null
hackerb9

0

swapon / swapoff将完全清除交换空间,但是您也可以通过/ proc文件系统释放其中的一些空间。您想要第一个:

# To free pagecache
echo 1 > /proc/sys/vm/drop_caches

# To free dentries and inodes
echo 2 > /proc/sys/vm/drop_caches

# To free pagecache, dentries and inodes
echo 3 > /proc/sys/vm/drop_caches

通过http://linux-mm.org/Drop_Caches


3
根据定义,交换内存不是高速缓存。删除缓存几乎不可能更改交换中的任何内容。另外,最好使用sysctl而不是直接覆盖proc文件系统中的文件。sysctl vm.drop_caches=X。同样,sysctl更易于sudo。
朱利诺

@julian虚拟内存= ram +交换iirc。应用程序和缓存都使用虚拟内存。但是我认为,在运算需要明确的一切,但缓存从交换,因为我怀疑那些真正有什么影响了他。
xenoterracide

@xenoterracide:缓存仅在实际的RAM内存中有意义。将缓存存储在交换中是没有意义的,它们是完全相反的。交换是系统物理RAM不足时使用的慢速内存; 高速缓存是当系统具有大量未使用的物理RAM时使用的快速内存。
朱利诺

@juliano是的,我知道,但是我相信它们都使用虚拟内存存储,尽管缓存可能只存储在RAM中。老实说,在这里删除缓存毫无意义,imo。
xenoterracide 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.