Program memory usage
There are several reasons why one might want to figure out how much memory a certain program requires. This article presents two methods for determining memory usage of a program in linux/unix compatible environments.
Checking program memory usage with pmap
The pmap program available on linux/unix platforms reports memory map of a running process. The pmap takes the process ID as argument. For example, the following command shows memory usage of a vim session :
pmap -x 7398
The PID 7398 was obtained using the ps command. The result of the pmap command above is the following :
7398: vim test 08048000 1556K r-x-- /usr/bin/vim.basic 081db000 24K rw--- [ anon ] b7fe2000 308K rw--- /usr/lib/libpython2.6.so.1.0 ... b803f000 4K rw--- /usr/lib/libgpm.so.2.0.0 b8094000 4K rw--- /lib/libncurses.so.5.7 b8099000 4K r---- /usr/lib/gconv/EUC-JP.so b80c3000 4K rw--- /lib/ld-2.9.so bfad5000 84K rw--- [ stack ] total 7704K
The last line starting with 'total' indicates that the bash program uses a total of 7704KB of memory. Note that the reported total memory usage is based on the current snapshot of the current memory map. The program may use more memory if at certain point it dynamically allocates memory.
Valgrind Massif heap profiler
The Valgrind tool suite provides a number of debugging and profiling tools that help make programs faster and more correct.
The Massif is the heap profiler tool of valgrind . It measures how much heap memory your program uses. This includes both the useful space, and the extra bytes allocated for book-keeping and alignment purposes.
Heap profiling is useful when you want to know the peak memory usage of a program, and when your program does not run for long enough to run the pmap command.
To use the valgrind massif heap profiler, you need to first run valgrind as follows :
valgrind --tool=massif --depth=1 prog prog-args
Where prog and prog-args are the program you want to profile and the corresponding arguments. The –depth=1 option is used to reduce the granularity of heap memory inspection, since we are not debugging memory usage and only interested in the total memory usage.
In our case, we run vim without arguments (valgrind –tool=massif vim), then perform some file editing then exiting.
This will produce a file massif.out.xxxx that we will use as input for the ms_print utility to obtain the actual memory usage report. This is done by invoking ms_print as follows :
ms_print massif.out.xxxx
The resulting output will be :
--------------------------------------------------------------------------------
Command: vim
Massif arguments: --depth=1
ms_print arguments: massif.out.7615
--------------------------------------------------------------------------------
KB
877.6^ # .. ...
| , @# :: :::
| @@ @# :: :::
| : @@ @# :: :::
| : @@ @# :: :::
| , : @@ @# :: :::
| . ..@ : @@ @# :: :::
| : ::@ : @@ @# :: :::
| :: ::@ : @@ @# :: ::: :::@:: :::@
| ,. .: :: ::@ : @@ @# :: ::: :::@:: :::@
| .@@: :: :: ::@ : @@ @# :: ::: :::@:: :::@
| .: :::: :@@: :: :: ::@ : @@ @# :: ::: :::@:: :::@
| ..:@ :: :::: :@@: :: :: ::@ : @@ @# :: ::: :::@:: :::@
| , ::::@ :: :::: :@@: :: :: ::@ : @@ @# :: ::: :::@:: :::@
| , : @ ::::@ :: :::: :@@: :: :: ::@ : @@ @# :: ::: :::@:: :::@
| .: @ : @ ::::@ :: :::: :@@: :: :: ::@ : @@ @# :: ::: :::@:: :::@
| . :: @ : @ ::::@ :: :::: :@@: :: :: ::@ : @@ @# :: ::: :::@:: :::@
| :: :: @ : @ ::::@ :: :::: :@@: :: :: ::@ : @@ @# :: ::: :::@:: :::@
| . : :: :: @ : @ ::::@ :: :::: :@@: :: :: ::@ : @@ @# :: ::: :::@:: :::@
| : : :: :: @ : @ ::::@ :: :::: :@@: :: :: ::@ : @@ @# :: ::: :::@:: :::@
0 +----------------------------------------------------------------------->Mi
0 122.3
Number of snapshots: 53
Detailed snapshots: [7, 9, 14, 22, 23, 31, 33, 34, 35, 36 (peak), 45, 51]
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
0 0 0 0 0 0
1 3,400,849 67,856 63,438 4,418 0
2 5,910,026 96,208 82,583 13,625 0
3 9,301,525 141,336 114,196 27,140 0
4 11,718,411 167,968 132,652 35,316 0
5 15,268,708 202,704 156,741 45,963 0
6 17,712,798 224,992 172,064 52,928 0
7 21,116,113 252,800 191,160 61,640 0
75.62% (191,160B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->73.68% (186,271B) 0x81167D6: lalloc (in /usr/bin/vim.basic)
|
->01.93% (4,889B) in 16 places, all below massif's threshold (01.00%)
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
8 24,270,649 278,808 209,494 69,314 0
9 27,073,846 297,536 222,283 75,253 0
74.71% (222,283B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->73.06% (217,394B) 0x81167D6: lalloc (in /usr/bin/vim.basic)
|
->01.64% (4,889B) in 16 places, all below massif's threshold (01.00%)
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
10 30,479,325 324,392 241,523 82,869 0
11 32,585,346 337,648 250,600 87,048 0
12 34,937,065 351,312 259,880 91,432 0
13 37,333,012 366,872 270,952 95,920 0
14 39,013,404 375,616 276,910 98,706 0
73.72% (276,910B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->72.42% (272,021B) 0x81167D6: lalloc (in /usr/bin/vim.basic)
|
->01.30% (4,889B) in 16 places, all below massif's threshold (01.00%)
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
15 41,423,053 389,384 286,501 102,883 0
16 43,923,054 406,336 298,860 107,476 0
17 46,494,139 418,184 308,225 109,959 0
18 48,457,625 422,336 311,957 110,379 0
19 50,454,076 421,744 309,886 111,858 0
20 52,541,357 424,728 311,658 113,070 0
21 56,046,990 446,808 330,171 116,637 0
22 57,662,662 456,464 339,167 117,297 0
74.30% (339,167B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->73.07% (333,538B) 0x81167D6: lalloc (in /usr/bin/vim.basic)
|
->01.23% (5,629B) in 32 places, all below massif's threshold (01.00%)
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
23 60,042,335 473,696 351,373 122,323 0
74.18% (351,373B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->72.91% (345,392B) 0x81167D6: lalloc (in /usr/bin/vim.basic)
|
->01.26% (5,981B) in 32 places, all below massif's threshold (01.00%)
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
24 61,668,471 475,664 352,964 122,700 0
25 64,254,132 486,848 362,044 124,804 0
26 66,803,325 515,576 386,287 129,289 0
27 70,517,588 561,016 428,118 132,898 0
28 72,147,744 618,032 477,712 140,320 0
29 75,016,378 620,176 479,280 140,896 0
30 77,921,372 622,328 480,844 141,484 0
31 79,910,907 673,456 517,432 156,024 0
76.83% (517,432B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->75.09% (505,701B) 0x81167D6: lalloc (in /usr/bin/vim.basic)
|
->01.74% (11,731B) in 40 places, all below massif's threshold (01.00%)
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
32 82,985,534 771,784 598,516 173,268 0
33 86,854,317 817,640 639,179 178,461 0
78.17% (639,179B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->76.74% (627,448B) 0x81167D6: lalloc (in /usr/bin/vim.basic)
|
->01.43% (11,731B) in 40 places, all below massif's threshold (01.00%)
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
34 88,436,612 839,944 655,169 184,775 0
78.00% (655,169B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->76.60% (643,438B) 0x81167D6: lalloc (in /usr/bin/vim.basic)
|
->01.40% (11,731B) in 40 places, all below massif's threshold (01.00%)
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
35 90,886,012 864,912 677,205 187,707 0
78.30% (677,205B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->76.94% (665,474B) 0x81167D6: lalloc (in /usr/bin/vim.basic)
|
->01.36% (11,731B) in 40 places, all below massif's threshold (01.00%)
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
36 94,370,797 898,712 706,052 192,660 0
78.56% (706,052B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->77.22% (693,969B) 0x81167D6: lalloc (in /usr/bin/vim.basic)
|
->01.34% (12,083B) in 40 places, all below massif's threshold (01.00%)
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
37 96,321,715 876,696 683,477 193,219 0
38 98,274,530 878,720 685,221 193,499 0
39 101,835,680 888,944 695,722 193,222 0
40 103,881,055 889,016 695,768 193,248 0
41 106,092,033 888,952 695,732 193,220 0
42 109,171,195 548,280 412,961 135,319 0
43 111,133,276 550,656 414,848 135,808 0
44 113,190,282 550,376 414,645 135,731 0
45 115,145,024 557,120 420,834 136,286 0
75.54% (420,834B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->73.43% (409,103B) 0x81167D6: lalloc (in /usr/bin/vim.basic)
|
->02.11% (11,731B) in 40 places, all below massif's threshold (01.00%)
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
46 117,246,258 550,848 414,903 135,945 0
47 119,194,607 553,224 416,827 136,397 0
48 121,220,195 552,792 416,626 136,166 0
49 123,377,661 553,176 416,819 136,357 0
50 124,961,128 555,048 418,504 136,544 0
51 126,673,425 554,832 418,196 136,636 0
75.37% (418,196B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->73.32% (406,817B) 0x81167D6: lalloc (in /usr/bin/vim.basic)
|
->02.05% (11,379B) in 40 places, all below massif's threshold (01.00%)
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
52 128,256,865 556,632 419,776 136,856 0
Valgrind takes snapshots of the memory usage at each instruction and creates an entry if memory usage has changed.The graph indicated the memory usage through the execution of the program, we can see that vim used a maximum of 877.6KB at a certain time. Just under the graph, there is table with snapshot identifiers. The commentary (peak) indicates the snapshot that corresponds to maximum memory usage during the vim session.
| Labels: unix, coding |
|

Comment