스왑 공간에서 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_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
이것은 스택 교환에서 본 것 중 가장 멋진 것 중 하나입니다. 이것을 게시 해 주셔서 감사합니다! 이것에서 뽑아 낼 좋은 너겟이 너무 많습니다.
— 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.