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?

  • 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

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)

| 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

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())
    ## Read the readable mapped ranges
    mem_file = open("/proc/" + pid + "/mem", 'r', 0)
    for r in ranges:
        if r[2] == 'r':
            chunk = mem_file.read(r[1] - r[0])
            print chunk,
    ## Cleanup
    ptrace(False, int(pid))

if __name__ == "__main__":
    for pid in sys.argv[1:]:

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

unswap () {
  cat_proc_mem "$@" >/dev/null
| improve this answer | |
  • 2
    This is seriously one of the coolest things I've ever seen on stack exchange. Kudos for posting this! There are so many good nuggets to pull from this. – Dan Nov 8 '15 at 4:40
  • Unformatunately I wasn't able to get this script working. With python 2 it shows error that the value r[0] is too big. On python 3 (after fixing a few minor issues) I get OSError: [Errno 5] Input/output error at chunk = mem_file.read(r[1] - r[0]) and the program I used it on hangs in both cases. – barteks2x Mar 21 '17 at 13:35
  • @Barteks2x I'm sorry, I don't have the time right now to make this script error-proof. It does work for me, at least on machines that don't have too many security restrictions (the technique uses some debugging interfaces that are disabled on hardened setups). The program is suspended while it's being traced, send it a SIGCONT (kill -CONT 1234 where 1234 is the PID) to resume it. – Gilles 'SO- stop being evil' Mar 21 '17 at 14:47
  • @Barteks2x: I've added some error checking here. This makes the script work even on IOErrors from /dev/dri/card0 and OverflowErrors from [vsyscall]. (It also prints out what the problem area was). – hackerb9 Jul 24 '17 at 17:57

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

| improve this answer | |
  • 4
    gcore $pid is also available outside of gdb (as a small wrapper script) – Tobu Jan 15 '14 at 12:36
  • gcore has no way to write to /dev/null, which is what you'd want if you were trying to force a process back into memory. However, you can do it in a single command like so: gdb --batch -p $pid -ex "gcore /dev/null" 2>/dev/null – hackerb9 Jul 24 '17 at 18:11

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

| 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
  • 1
    @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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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