Saturday, November 12, 2011

Tweaking stack size of Linux processes to reduce swapping

Since upgrading to Kubuntu 11.10, my laptop has been slow. Slow because it’s been accessing the hard disk a lot. I incidentally opened system monitor yesterday and found that more than 1GB of swapping space was in use although only about 1.1GB of the total 2GB RAM was in use. That doesn’t sound right. The computer shouldn’t swap when about half of the RAM is unused.

My friend Abhay had once told me about thread stack size configuration of Linux (Unix?) processes. This configuration specifies how much RAM is given to each thread for its stack. I ran the following command to see how much was the current stack size:

% ulimit -s
8192

That’s 8192KB allocated for each thread. With some Googling around I figured this was a huge number. Windows allocates only 1MB by default. For a machine that’s low on RAM like mine, 8MB for stack is ludicrous. I decided to make it 2MB instead. Unsurprisingly, I wasn’t the first to try to do something like this; a thread on LinuxQuestions.org explained that I can edit /etc/security/limits.conf to set the default size.

I added the following lines to my /etc/security/limits.conf:

* soft stack 2048
* hard stack 2048

(Only root can modify this file; you’ll need to use sudo.) To apply the configuration changes I restarted the machine. After restarting, now my machine is using about 1.4GB of RAM and about 80MB of swap. No need to mention, everything is fast as it used be.

Linux does not actually allocate that much memory to the process. The rlimit specifies how much memory the process is allowed to use for its stack but it's actually allocated on demand when the process tries to access it.

However, glibc will allocate thread stacks based on the rlimit by default. That seems a tad excessive, but it's unclear to me if the kernel will assign all the memory when processing the mmap, as it could also map it to the zero page frame and be done with it until the first write access occurs.