How to force a swapped-out zsh process to swap in?
Asked Answered
A

3

6

I usually have many long-running zsh processes (in spread out over various screen sessions) on my computer, but shells that haven't been used for a while tend to be swapped out. When I switch to such a swapped-out shell and press enter (at an empty prompt) it takes many seconds before the shell responds and a new prompt is displayed (but after that it resumes working perfectly).

To lessen my annoyance I'd like to have a command (e.g. unswap PID) that I can invoke (from another, already responding shell) to force a shell swap in.

Any ideas on how to achieve this?

P.S. I started off by looking around for a command to ask the system to swap in any process – but I have found no such thing, making me believe that this is not possible. I've here focused my question to zsh, since this is the case that really interests me, and I'm hoping there might be a solution for that particular case. If you have a more general method that would work for any process (and not just zsh) that would be quite welcome too.

P.P.S. At first I thought of using a trap function inside my shell, which then did some activity (anything) enough to cause the shell to swap in. Having tried this with the WINCH signal however, I've found that it doesn't work. (Maybe the signal is not delivered to a swapped out process? Are any signals?)


EDIT: In my typical case I have a bunch of zsh processes running, and then I've left my browser open (with multiple Gmail, Facebook etc tabs) for a bit too long, causing the browser to hoard all of the available RAM and squeezing everything else out into swap. The desktop goes unresponsive for a while, but that clears up kinda quickly. However, when reattaching to a screen session each shell have to be waken up manually (going through them and pressing enter in each shell).

Apposite answered 3/8, 2013 at 6:18 Comment(5)
swapped processes do get signals. Maybe you could swapoff and swapon .... assuming there is enough RAM to do that.Shove
“Swap in” is a difficult concept: if you swap in all the files and libraries that the process maps, that could include a lot of data that it isn't going to use. See how to “unswap” my desktop on Unix & Linux (same question except not specifically about zsh).Acetylcholine
@Gilles Thanx for pointing to that question, that was precisely what I needed to find the answer.Apposite
Hmm. This question probably belong on the Unix & Linux stackexchange site, rather than here. – Can questions be moved between sites?Apposite
@ZrajmCAkfohg If you're approaching this as a user then it belongs on Unix & Linux. If you want to program this feature into zsh, then it belongs on Stack Overflow. It's borderline. Matt provided an SO answer, yours is a U&L answer. If you want this question migrated, you can flag for it — but it would be a duplicate of the question I linked to, so there isn't a lot of use for migrating.Acetylcholine
A
2

As mentioned in this answer one can use gdb to dump the memory of a process in order to get it unswapped.

I also found out here that there is a gcore script to do this directly from the command line (instead of first having to start gdb and then execute additional commands inside of it), so invoking:

gcore -o /tmp/SOMETHING PID1 PID2 PID3

will cause programs with PID1, PID2 and PID3 to become unswapped, and dump their contents to files /tmp/SOMETHING.PID1, /tmp/SOMETHING.PID2 etc.

There is also a Python script in this answer which does the same thing. Though, admittedly – as a response to this question – in a much nicer fashion, since this scripts output the dump on STDOUT which we can pipe straight to hell (uhm, I mean /dev/null, of course) since we're only interested in the side effect of unswapping anyway.

Apposite answered 6/9, 2013 at 8:5 Comment(1)
Since gcore is a shell script, you can edit the script not to save the dump output in a file, but into /dev/null instead. There is a limit on comment size, so I can't post that script here; see my separate answer.About
A
1

Since gcore is a shell script, you can edit the script not to save the dump output in a file, but into /dev/null instead, e.g.

#!/bin/sh -u

# Use </dev/null to avoid touching interactive terminal if it is
# available but not accessible as GDB would get stopped on SIGTTIN.
#
exec </dev/null

for pid do
        gdb --nx --batch --readnever \
            -ex "set pagination off" -ex "set height 0" -ex "set width 0" \
            -ex "attach $pid" -ex "gcore /dev/null" -ex detach -ex quit
done

The above does give an error Memory read failed for corefile section, but it works well enough to pull most/all of the process into memory and out of swap.

About answered 2/11, 2021 at 7:21 Comment(0)
B
0

Have you tried/can you decrease the kernel swappiness value so zsh is less likely to be swapped out?

If you're willing to recompile zsh, you could insert a call to mlockall( MCL_CURRENT | MCL_FUTURE ) in main(). This prevents it from being swapped out in the first place.

Or add a signal handler that calls mlockall( MCL_CURRENT ) followed by munlockall().

Blakemore answered 14/8, 2013 at 15:41 Comment(2)
Well, I don't want to force zsh to never swap out, I just want to be able to swap it in again on command. (With sometimes 50+ shells running on my machine for months on end, I think it better not to force all of them to stay in my precious RAM.) – Likewise with changing the swappiness value. I don't want change to much in my system, I just want the option of manually waking my processes up from their swappy slumber.Apposite
"you can see that you cannot use the Linux swappiness value to influence swap’s behavior with respect to RAM usage. It just doesn’t work like that." howtogeek.com/449691/…About

© 2022 - 2024 — McMap. All rights reserved.