GNU/Linux >> Linux の 問題 >  >> Linux

実行中のすべてのアプリケーションをスワップ領域から RAM に再ロードする方法は?

次の簡単な 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 "[email protected]" >/dev/null
}

本当に十分な RAM が再び利用できる場合は、次のシーケンスを (root として) 使用できます:

$ swapoff -a
$ swapon -a

(すべてのアプリケーションの明示的なスワップインを強制するため)

(Linux を使用していると仮定します)


完全を期すために、GDB はプロセス イメージをダンプできます。私はそれがスワップを解除することを確認しませんでしたが、そうする必要があります---プロセスメモリ全体を読み取る他の方法はありません:
gdb -p $mypid
に続く
(gdb) gcore /tmp/myprocess-core
Saved corefile /tmp/myprocess-core


Linux
  1. Debian 11 にスワップ領域を追加する方法

  2. Linux でスワップ領域を増やす方法

  3. スワップ パーティションのサイズはどれくらいですか?

  1. Linuxシステムのスワップスペースの概要

  2. Linuxでスワップスペースを作成または増やす方法

  3. Ubuntu 22.04 でスワップ領域を追加する方法

  1. Linux でスワップ領域を追加する方法

  2. クリップボードから nano に貼り付けるには?

  3. スワップするためにより多くのスペースを割り当て、そのサイズを RAM よりも大きくする方法は?