A Way to Determine a Process'S "Real" Memory Usage, I.E. Private Dirty Rss

How can I measure the actual memory usage of an application or process?

With ps or similar tools you will only get the amount of memory pages allocated by that process. This number is correct, but:

  • does not reflect the actual amount of memory used by the application, only the amount of memory reserved for it

  • can be misleading if pages are shared, for example by several threads or by using dynamically linked libraries

If you really want to know what amount of memory your application actually uses, you need to run it within a profiler. For example, Valgrind can give you insights about the amount of memory used, and, more importantly, about possible memory leaks in your program. The heap profiler tool of Valgrind is called 'massif':

Massif is a heap profiler. It performs detailed heap profiling by taking regular snapshots of a program's heap. It produces a graph showing heap usage over time, including information about which parts of the program are responsible for the most memory allocations. The graph is supplemented by a text or HTML file that includes more information for determining where the most memory is being allocated. Massif runs programs about 20x slower than normal.

As explained in the Valgrind documentation, you need to run the program through Valgrind:

valgrind --tool=massif <executable> <arguments>

Massif writes a dump of memory usage snapshots (e.g. massif.out.12345). These provide, (1) a timeline of memory usage, (2) for each snapshot, a record of where in your program memory was allocated. A great graphical tool for analyzing these files is massif-visualizer. But I found ms_print, a simple text-based tool shipped with Valgrind, to be of great help already.

To find memory leaks, use the (default) memcheck tool of valgrind.

What is dirty private memory?

Talking about the memory non-decrease even after freeing some chunks, you'd better use mmap in anonymous mode like this:

mmap(NULL, chunck_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

which maps no file descriptor and returns a pointer to a memory chunk which is immediately returned to the OS when you unmap it. However, mmap requires a system call, which is slower than malloc. So, you should use mmap for allocating large pages.

How to display processes that are using memory in an given range

This will list processes as expected. Remember that ps shows memory size in kilobytes.

ps -u 1000 -o pid,user,stime,rss \
| awk '{if($4 > 50000 && $4 < 100000){ print $0 }}' \
| sort -n -k 4,4

Command output:

 3407 luis.mu+ 10:30 51824
3523 luis.mu+ 10:30 66108
3410 luis.mu+ 10:30 71060
3595 luis.mu+ 10:30 74340
3609 luis.mu+ 10:30 77772
18550 luis.mu+ 16:47 93616

In that case it's showing only 4 fields for user id 1000. To show all processes use

ps -e -o pid,user,stime,rss

From the ps(3) man page under STANDARD FORMAT SPECIFIERS:

rss

resident set size, the non-swapped physical memory that a task has used (inkiloBytes)

If you want to show more fields, check the man page and add fields to -o option.

Is this explanation about VSS/RSS/PSS/USS accurate?

That sounds correct and also lines up with the description found here: http://elinux.org/Android_Memory_Usage

From the page...

  • Vss = virtual set size
  • Rss = resident set size
  • Pss = proportional set size
  • Uss = unique set size


Related Topics



Leave a reply



Submit