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


20

デスクトップでメモリが不足してスワップが頻繁に発生する場合、RAMを浪費しているアプリケーションを解放または強制終了します。しかし、その後、すべてのデスクトップ/アプリケーションがスワップされ、ひどく遅くなります。デスクトップ/アプリケーションを「アンスワップ」する方法を知っていますか(スワップスペースからRAMにリロードします)?


swapon/ を使用してシステム全体をスワップ解除するのではなくswapoff(現在受け入れられている答えが示唆するように)、プロセスメモリーをダンプすることでディスプレイマネージャーとそのすべての子をスワップ解除することができます(アンスワップを強制します)。stackoverflowの「スワップアウトされたzshプロセスを強制的にスワップインする方法」も参照してください 。
zrajm

回答:


16

本当に十分なRAMを再び使用できる場合は、このシーケンスを(ルートとして)使用できます。

$ swapoff -a
$ swapon -a

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

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


IIRCを使用しない場合でも、可能な限り多くのデータを移動します。キャッシュとcoを破損する可能性がありますが。時々便利です。
マチェイピエチョトカ

18

次の手っ取り早い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
}

2
これは、スタック交換で見た中で最もクールなものの1つです。これを投稿してくれてありがとう!これから引き出すには非常に多くの良いナゲットがあります。
ダン

なんとなく、このスクリプトを機能させることができませんでした。python 2では、値r [0]が大きすぎるというエラーが表示されます。python 3で(いくつかの小さな問題を修正した後)OSErrorが発生します:[Errno 5]チャンク= mem_file.read(r [1]-r [0])で入出力エラーが発生し、両方でハングしましたケース。
barteks2x

@ Barteks2x申し訳ありませんが、このスクリプトのエラーを防ぐための時間は今のところありません。少なくとも、セキュリティの制限があまりないマシンでは機能します(強化されたセットアップでは無効になっているデバッグインターフェイスを使用します)。プログラムはトレース中に中断されます。SIGCONT(kill -CONT 12341234はPID)を送信して再開します。
ジル 'SO-悪であるのをやめる'

@ Barteks2x:ここにいくつかのエラーチェックを追加しまし。これにより、スクリプトは/ dev / dri / card0のIOErrorおよび[vsyscall]のOverflowErrorsでも動作します。(また、問題領域が何であったかを出力します)。
hackerb9

6

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


3
gcore $pid(小さなラッパースクリプトとして)gdbの外部でも利用可能です
東武14年

gcoreには/ dev / nullに書き込む方法がありません。これは、プロセスを強制的にメモリに戻そうとする場合に必要なものです。ただし、次のように1つのコマンドで実行できます 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
定義上、スワップメモリ​​はキャッシュではありません。キャッシュを削除しても、スワップ内の何かが変更されることはほとんどありません。また、procファイルシステムのファイルを直接上書きするのではなく、sysctlを使用することをお勧めします。sysctl vm.drop_caches=X。また、sysctlはsudoに簡単です。
ジュリアーノ

@julian仮想メモリ= ram +スワップiirc。アプリケーションとキャッシュの両方が仮想メモリを使用します。しかし、私はOPは明らかすべてに必要だと思いますが、私はそれらが本当に彼に影響を与える何です疑うよう、スワップからキャッシュ。
xenoterracide

@xenoterracide:キャッシュは、実際のRAMメモリでのみ意味があります。スワップにキャッシュを保存するのは無意味であり、完全に正反対です。スワップは、システムの物理RAM不足しているときに使用される低速メモリです。キャッシュは、システムに未使用の物理RAMたくさんあるときに使用される高速メモリです
ジュリアーノ

@julianoはい、わかっていますが、両方とも仮想メモリを使用して保存されていると思いますが、キャッシュはRAMにのみ保存される可能性があります。正直なところ、ここでキャッシュを削除しても意味がありません。
xenoterracide
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.