내 데스크톱의 메모리가 부족하고 많이 교체되면 RAM을 낭비하는 응용 프로그램을 해제하거나 종료합니다. 그러나 그 후 모든 데스크탑/응용 프로그램이 스왑되고 속도가 매우 느려집니다. 데스크탑/응용 프로그램을 "스왑 공간에서 RAM으로 다시 로드"(스왑 공간에서 다시 로드)하는 방법을 알고 있습니까?
답변1
다음의 빠르고 더러운 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 "$@" >/dev/null
}
답변2
사용 가능한 RAM이 충분한 경우 루트로 다음 순서를 사용할 수 있습니다.
$ swapoff -a
$ swapon -a
(모든 애플리케이션을 명시적으로 교체하도록 강제)
(리눅스를 사용한다고 가정)
답변3
완전성을 위해 GDB는 프로세스 이미지를 덤프할 수 있습니다. 스왑을 취소하는지 확인하지는 않았지만
gdb -p $mypid
그렇게 해야 합니다. 전체 프로세스 메모리를 읽을 수 있는 다른 방법은 없습니다.
(gdb) gcore /tmp/myprocess-core
Saved corefile /tmp/myprocess-core
답변4
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