One day last week, I tried to open my terminal and I was surprised by this error:

-bash: xmalloc: cannot allocate 4000000016 bytes

Wat

Bash was trying to allocate 4Gb of memory? Why?

Looking at my Frankenstein .bashrc file, I decided that it was time to try to understand what each variable actually does. I like to keep everything I ever executed in my history, with timestamps and multi line support. I started cleaning it, and found out that this issue stopped happening once I removed the variables responsible for my bash’s history size.

These are the ones to blame:

export HISTSIZE=500000000

export HISTFILESIZE=500000000

I had both $HISTSIZE and $HISTFILESIZE set up to 500,000,000 lines. It's a reasonable number, right? \s

But what do they actually do?

HISTFILESIZE : the maximum number of commands to store in your $HISTFILE file, which by default is ~/.bash_history .

: the maximum number of commands to store in your file, which by default is . $HISTSIZE : the maximum number of commands that will be kept in memory and flushed to disk (into $HISTFILE ) once you exit the shell. It is also used to load the last $HISTSIZE lines from your history file into memory when you open a new shell.

Now back to the problem. Let’s invoke our friend strace . I left only the important lines of the trace:

$ strace -f bash

...

[pid 11677] open("/home/carla/.bash_history", O_RDONLY) = 3

[pid 11677] fstat(3, {st_mode=S_IFREG|0600, st_size=16755, ...}) = 0

[pid 11677] read(3, "ls

#1478028902

./i3-get-window-c"..., 16755) = 16755

[pid 11677] close(3) = 0

[pid 11677] chown("/home/carla/.bash_history", 1000, 100) = 0

[pid 11677] stat("/home/carla/.bash_history", {st_mode=S_IFREG|0600, st_size=16755, ...}) = 0

[pid 11677] open("/home/carla/.bash_history", O_RDONLY) = 3

[pid 11677] fstat(3, {st_mode=S_IFREG|0600, st_size=16755, ...}) = 0

[pid 11677] read(3, "ls

#1478028902

./i3-get-window-c"..., 16755) = 16755

[pid 11677] close(3) = 0

[pid 11677] mmap(NULL, 4000002048, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)

[pid 11677] brk(0xf0e0a000) = 0x2746000

[pid 11677] mmap(NULL, 4000137216, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)

[pid 11677] mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7f9e145ae000

[pid 11677] munmap(0x7f9e145ae000, 61153280) = 0

[pid 11677] munmap(0x7f9e1c000000, 5955584) = 0

[pid 11677] mprotect(0x7f9e18000000, 135168, PROT_READ|PROT_WRITE) = 0

[pid 11677] mmap(NULL, 4000002048, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)

[pid 11677] write(2, "-bash: xmalloc: cannot allocate "..., 49-bash: xmalloc: cannot allocate 4000000016 bytes ) = 49

[pid 11677] exit_group(2) = ?

[pid 11677] +++ exited with 2 +++

...

strace is telling me that as part of starting bash, it reads my .bash_history and then allocate memory right after. It was trying to allocate 4,000,000,016 bytes (4Gb) of memory. My first reaction was to blame Google Chrome for using all of my memory, causing memory starvation of my dear friend, bash.