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

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

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

答案1

以下快速而肮脏的 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

如果您确实有足够的 RAM 可用,您可以使用以下序列(作为 root):

$ swapoff -a
$ swapon -a

(强制显式换入所有应用程序)

(假设你使用的是linux)

答案3

为了完整起见,GDB 可以转储进程映像。我没有检查它是否取消交换它,但它必须这样做——没有其他方法可以读取整个进程内存:
gdb -p $mypid
然后是
(gdb) gcore /tmp/myprocess-core
Saved corefile /tmp/myprocess-core

答案4

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

相关内容