Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

If my desktop run out of memory and swaps a lot then I free or kill the application wasting my RAM. But, after that, all my desktop/applications have been swapped and are horribly slow, do you know a way to "unswap" (reload from swap space into RAM) my desktop/applications?

share|improve this question
    
Rather than to unswap the entire system using swapon/swapoff (as the currently accepted answer suggests), you might want to unswap your display manager and all its children by dumping their process memories (which force unswapping). See also “How to force a swapped-out zsh process to swap in?” on stackoverflow. –  zrajm Dec 13 '13 at 10:30

4 Answers 4

up vote 10 down vote accepted

If you really have enough RAM available again you can use this sequence (as root):

$ swapoff -a
$ swapon -a

(to force the explicit swap-in of all your applications)

(assuming that you are using linux)

share|improve this answer
    
Even if you don't IIRC it will move as much data as possible. While it may damage cache & co. it is sometimes useful. –  Maciej Piechotka Jan 21 '11 at 22:32
    
Thanks, i will try next time :) –  profy Jan 22 '11 at 10:43

swapon/swapoff will completely clear your swap space, but you can free some of it via the /proc file system too. You want the first one:

# 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

via http://linux-mm.org/Drop_Caches

share|improve this answer
3  
Swap memory is, by definition, not cache. Dropping the caches is very unlikely to change anything in the swap. Also, it is preferable to use sysctl instead of directly writing over files in the proc filesystem. sysctl vm.drop_caches=X. Also, sysctl is easier to sudo. –  Juliano Jan 21 '11 at 23:59
    
@julian virtual memory = ram + swap iirc. Both applications and caches use virtual memory. However I think that the op needs to clear everything but caches from swap, as I doubt those are really what's effecting him. –  xenoterracide Jan 22 '11 at 8:17
    
@xenoterracide: caches only make sense in real, RAM memory. It is pointless to store cache in the swap, they are complete opposites. Swap is slow memory used when the system is short on physical RAM; cache is fast memory used when the system has plenty of unused physical RAM. –  Juliano Jan 22 '11 at 12:49
    
@juliano yes I know, but I believe they are both stored using virtual memory, though it's possible that caches only get stored in RAM. honestly dropping the caches makes no sense here, imo. –  xenoterracide Jan 22 '11 at 13:58

The following quick-and-dirty python script dumps the memory of a process to stdout. This has the side effect of loading any swapped out page or mapped file. Call it as cat_proc_mem 123 456 789 where the arguments are process IDs.

This script is completely specific to Linux. It may be adaptable to other systems with a similar /proc structure (Solaris?), but forget about running it on e.g. *BSD. Even on Linux, you may need to change the definition of c_pid_t and the values of PTRACE_ATTACH and PTRACE_DETACH. This is a proof-of-principle script, not meant as an example of good programming practices. Use at your own risk.

Linux makes the memory of a process available as /proc/$pid/mem. Only certain address ranges are readable. These ranges can be found by reading the memory mapping information from the text file /proc/$pid/maps. The pseudo-file /proc/$pid/mem cannot be read by all processes that have the permission to read it: the reader process must have called 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)

See also more information on /proc/$pid/mem.

unswap () {
  cat_proc_mem "$@" >/dev/null
}
share|improve this answer

Just for completeness, GDB can dump process image. I didn't check that it unswaps it, but it has to---there's no other way to read the whole process memory:
gdb -p $mypid
followed by
(gdb) gcore /tmp/myprocess-core
Saved corefile /tmp/myprocess-core

share|improve this answer
    
gcore $pid is also available outside of gdb (as a small wrapper script) –  Tobu Jan 15 at 12:36

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.