回答:
本当に十分なRAMを再び使用できる場合は、このシーケンスを(ルートとして)使用できます。
$ swapoff -a
$ swapon -a
(すべてのアプリケーションの明示的なスワップインを強制するため)
(Linuxを使用していると仮定)
次の手っ取り早いpythonスクリプトは、プロセスのメモリを標準出力にダンプします。これには、スワップアウトされたページまたはマップされたファイルをロードするという副作用があります。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プロセスを強制的にスワップインする方法」も参照してください 。