GNU/Linux >> Linux Esercitazione >  >> Linux

Come ricaricare tutte le applicazioni in esecuzione dallo spazio di swap nella RAM?

Il seguente script python veloce e sporco scarica la memoria di un processo su stdout. Questo ha l'effetto collaterale di caricare qualsiasi pagina scambiata o file mappato. Chiamalo come cat_proc_mem 123 456 789 dove gli argomenti sono ID di processo.

Questo script è completamente specifico per Linux. Potrebbe essere adattabile ad altri sistemi con un /proc simile structure (Solaris?), ma dimentica di eseguirlo ad es. *BSD. Anche su Linux, potrebbe essere necessario modificare la definizione di c_pid_t e i valori di PTRACE_ATTACH e PTRACE_DETACH . Questo è uno script di prova di principio, non inteso come un esempio di buone pratiche di programmazione. Utilizzare a proprio rischio.

Linux rende disponibile la memoria di un processo come /proc/$pid/mem . Sono leggibili solo determinati intervalli di indirizzi. Questi intervalli possono essere trovati leggendo le informazioni sulla mappatura della memoria dal file di testo /proc/$pid/maps . Lo pseudo-file /proc/$pid/mem non può essere letto da tutti i processi che hanno il permesso di leggerlo:il processo lettore deve aver chiamato 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)

Vedi anche maggiori informazioni su /proc/$pid/mem .

unswap () {
  cat_proc_mem "[email protected]" >/dev/null
}

Se hai di nuovo abbastanza RAM disponibile puoi usare questa sequenza (come root):

$ swapoff -a
$ swapon -a

(per forzare lo swap-in esplicito di tutte le tue applicazioni)

(supponendo che tu stia usando Linux)


Solo per completezza, GDB può eseguire il dump dell'immagine del processo. Non ho verificato che lo annulli, ma deve --- non c'è altro modo per leggere l'intera memoria del processo:
gdb -p $mypid
seguito da
(gdb) gcore /tmp/myprocess-core
Saved corefile /tmp/myprocess-core


Linux
  1. Un'introduzione allo spazio di scambio sui sistemi Linux

  2. Come aggiungere spazio di scambio su Ubuntu 22.04

  3. Come aggiungere spazio di swap in Linux

  4. Come aumentare lo spazio di swap su Linux

  5. Quanto deve essere grande la partizione di swap?

Come eseguire il backup di tutti i database MySQL dalla riga di comando

Come rimuovere tutti i caratteri di spazio bianco da un file di testo

Come cancellare la cache di memoria RAM e il buffer e lo spazio di scambio su Linux

Come trovare il nome del processo dal suo PID

Come controllare lo spazio di scambio in Linux

Come rimuovere Swap Space da Centos 7.x?