Wednesday, January 18, 2012

Exact memory usage of a Linux process

Understanding how memory utlisation works in Linux is somewhat complex. Even popular Linux tools such as 'top' and 'ps' do not report the actual true memory utilisation of a process, but rather an aggregation of the shared memory. This article will show you a nifty trick to identify the true memory utlisation of any Linux process.

Why 'ps' and 'top' are wrong? These tools often include the shared memory used by shared libraries rather than the actual private memory of the process. If we were to investigate something like memory leak management, we would want to know the real memory.

One easy way to get the true usage is by building a memory map using the 'pmap' tool and get the private writeable memory. This is done by using this command:

pmap -d <PID>

Let's see a typical example where we want to find the memory used by the 'sqlplus' process. The 'ps' tool reports around 41MB in total (Virtual Size: 33164KB, Resident Size: 8356KB). It looks quite big for a single 'sqlplus' process - infact it is big because 'ps' is also reporting the size of the shared libraries:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
oracle   30409  0.0  0.0  33164  8356 pts/0    S+    2011   0:00 sqlplus


Now, let's use pmap to determine the true memory usage:

$ pmap -d 30409
30409:   sqlplus
Address   Kbytes Mode  Offset           Device    Mapping
00110000    1552 r-x-- 0000000000000000 068:00003 libnnz11.so
00294000     148 rwx-- 0000000000184000 068:00003 libnnz11.so
002b9000       4 rwx-- 00000000002b9000 000:00000   [ anon ]
002ba000      76 r-x-- 0000000000000000 068:00003 libnsl-2.5.so
002cd000       4 r-x-- 0000000000012000 068:00003 libnsl-2.5.so
...
b7f17000     152 rw--- 00000000b7f17000 000:00000   [ anon ]
bf8e6000      80 rwx-- 00000000bf8e6000 000:00000   [ stack ]
bf8fa000       4 rw--- 00000000bf8fa000 000:00000   [ anon ]
mapped: 33164K    writeable/private: 2752K    shared: 424K


Pmap reports that the private memory of the 'sqlplus' process is 2.7MB (writeable/private: 2752K ) - this is infact the true memory utlised by the process - very much different from the 41MB reported earlier!