스왑 공간에서 RAM으로 실행중인 모든 응용 프로그램을 다시로드하는 방법은 무엇입니까?


20

데스크톱에 메모리가 부족하고 많이 스왑하면 RAM을 낭비하는 응용 프로그램을 해제하거나 중지합니다. 그러나 그 후 모든 데스크탑 / 응용 프로그램이 교환되었고 속도가 너무 느립니다. 데스크탑 / 응용 프로그램을 "스왑 공간에서 RAM으로 다시로드"하는 방법을 알고 있습니까?


swapon/를 사용하여 전체 시스템을 스왑 해제하는 대신 swapoff(현재 허용되는 답변에서 알 수 있듯이) 프로세스 메모리를 스왑 (해제 스왑 해제)하여 디스플레이 관리자와 모든 자식을 스왑 해제 할 수 있습니다. stackoverflow 에서“스왑 아웃 zsh 프로세스를 강제로 스왑 인하는 방법?” 도 참조하십시오 .
zrajm

답변:


16

사용 가능한 RAM이 충분한 경우이 시퀀스를 루트로 사용할 수 있습니다.

$ swapoff -a
$ swapon -a

(모든 응용 프로그램의 명시 적 스왑 인을 강제하기 위해)

(리눅스를 사용한다고 가정)


IIRC가 아니더라도 가능한 한 많은 데이터를 이동시킵니다. 캐시 및 공동에 손상을 줄 수 있지만 때로는 유용합니다.
Maciej Piechotka

18

다음의 더 빠르고 더러운 파이썬 스크립트는 프로세스의 메모리를 stdout에 덤프합니다. 스왑 아웃 페이지 또는 매핑 된 파일을로드하면 부작용이 발생합니다. cat_proc_mem 123 456 789인수가 프로세스 ID 인 것처럼 호출하십시오 .

이 스크립트는 Linux에만 해당됩니다. 유사한 /proc구조 (Solaris?)를 가진 다른 시스템에도 적용 할 수 있지만 * BSD 등에서 실행하는 것을 잊어 버리십시오. 심지어 리눅스에, 당신의 정의를 변경해야 할 수도 있습니다 c_pid_t및의 값 PTRACE_ATTACHPTRACE_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
이것은 스택 교환에서 본 것 중 가장 멋진 것 중 하나입니다. 이것을 게시 해 주셔서 감사합니다! 이것에서 뽑아 낼 좋은 너겟이 너무 많습니다.
Dan

비 형식적 으로이 스크립트를 작동시킬 수 없었습니다. 파이썬 2에서는 r [0] 값이 너무 크다는 오류가 표시됩니다. 파이썬 3에서 (몇 가지 사소한 문제를 수정 한 후) OSError : [Errno 5] 청크 입력 / 출력 오류 = mem_file.read (r [1]-r [0]) 및 내가 사용한 프로그램이 둘 다 중단됩니다. 사례.
barteks2x

@ Barteks2x 죄송합니다. 현재이 스크립트를 오류 방지 할 시간이 없습니다. 적어도 보안 제한이 너무 많은 시스템에서는 작동하지 않습니다 (이 기술은 강화 된 설정에서 비활성화 된 일부 디버깅 인터페이스를 사용합니다). 프로그램이 추적되는 동안 일시 중지되었습니다. SIGCONT ( kill -CONT 12341234는 PID 임)를 보내서 다시 시작하십시오.
Gilles 'SO- 악의를 멈춰라'

@ Barteks2x : 여기에 오류 검사를 추가 했습니다 . 따라서 스크립트는 / dev / dri / card0의 IOErrors 및 [vsyscall]의 OverflowErrors에서도 작동합니다. (문제 영역이 무엇인지 인쇄합니다.)
hackerb9

6

완벽을 기하기 위해 GDB는 프로세스 이미지를 덤프 할 수 있습니다. 전체 프로세스 메모리를 읽을 수있는 다른 방법이 없습니다 --- 나는 그것을 unswaps 확인하지 못했지만, 그것은에있다 :
gdb -p $mypid
다음에
(gdb) gcore /tmp/myprocess-core
Saved corefile /tmp/myprocess-core


3
gcore $pid는 작은 래퍼 스크립트로 gdb 외부에서도 사용 가능
Tobu

gcore는 / dev / null에 쓸 수있는 방법이 없습니다. 프로세스를 강제로 메모리로 되돌리려는 경우 원하는 것입니다. 그러나 다음과 같은 단일 명령으로 수행 할 수 있습니다. 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하기가 더 쉽습니다.
Juliano

@julian 가상 메모리 = ram + swap iirc. 응용 프로그램과 캐시 모두 가상 메모리를 사용합니다. 그러나 나는 영업 이익은 분명 모든 것을해야한다고 생각 하지만, 내가 그 정말 그를 초래 무슨이다 의심으로, 스왑에서 캐시.
xenoterracide

@xenoterracide : 캐시는 실제 RAM 메모리에서만 의미가 있습니다. 스왑에 캐시를 저장하는 것은 의미가 없으며 완전히 반대입니다. 스왑은 시스템이 물리적 RAM부족할 때 사용되는 느린 메모리입니다 . 캐시는 시스템 에 사용되지 않은 물리적 RAM많을 때 사용되는 빠른 메모리 입니다.
Juliano

@juliano 그렇습니다.하지만 캐시는 모두 RAM에 저장 될 수 있지만 가상 메모리를 사용하여 저장되어 있다고 생각합니다. 솔직히 캐시를 삭제하는 것은 이치에 맞지 않습니다.
xenoterracide
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.