Why does bash 4.3 keep allocating memory in a script

As you already discovered that this problem does not appear with dash, it seems to be obvious that there is a high probability that this is caused by a bug.

It does also grow if you are using bash-3.x but very slowly - still faster than with other shells.

I recommend you to make a bug-report against your version of bash.

BTW: I did some tests and there are only two shells where there is no growth at all - regardless how long you wait: mksh and the original Bourne Shell that was not yet converted to use malloc() instead of sbrk().

All other shells grow very slowly.


Bash saves each backgrounded process in a table of active jobs. Because you're spawning new jobs without explicitly checking the old ones, the table potentially increases without bound. The problem goes away if you disown the process after backgrounding it or check the exit status using jobs before launching the next background process.

For example, this version of your script does not increase in memory usage:

set -euf

# monitor a child process
# see if it's up

cpid=
while : ; do
    # if cpid isn't set, spawn child
    if [ -z "$cpid" ]; then
       "$@" &
       disown $!       # Don't waste memory on this red-headed child
       cpid="$!"
    fi

    # if child isn't active unset cpid
    if ps -o pid= -p "$cpid"; then
        :
    else
        cpid=
    fi

    sleep 1
done