Answers:
如果确实有足够的可用RAM,则可以使用以下顺序(以root用户身份):
$ swapoff -a
$ swapon -a
(以强制所有应用程序的显式交换)
(假设您使用的是Linux)
以下快速且肮脏的python脚本将进程的内存转储到stdout。这具有加载任何换出的页面或映射文件的副作用。将其称为cat_proc_mem 123 456 789
参数是进程ID的位置。
该脚本完全特定于Linux。它可能适用于其他具有类似/proc
结构的系统(Solaris?),但是不必在* BSD上运行它。即使是在Linux上,您可能需要更改的定义c_pid_t
和值PTRACE_ATTACH
和PTRACE_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
}
kill -CONT 1234
其中1234是PID)以恢复该程序。
仅出于完整性考虑,GDB可以转储过程映像。我没有检查它unswaps它,但它具有---有没有其他的方式来读取整个进程内存:
gdb -p $mypid
后跟
(gdb) gcore /tmp/myprocess-core
Saved corefile /tmp/myprocess-core
gcore $pid
也可以在gdb之外使用(作为一个小的包装脚本)
gdb --batch -p $pid -ex "gcore /dev/null" 2>/dev/null
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
sysctl vm.drop_caches=X
。同样,sysctl更易于sudo。
swapon
/ 来取消整个系统的交换swapoff
(如当前接受的答案所建议的那样),您可能不希望通过转储其进程存储器(强制进行交换)来交换显示管理器及其所有子级。另请参见 stackoverflow上的“如何强制换出的zsh进程换入?”。