pmap study: how to find a memory leak.
2011-11-17 17:28
465 查看
pmap is a good tool to report the memory map of a process. But how to make sure a process has memory leak, here is the tips:
1, if the virtual memory (VIRT) or writeable/private (‘pmap –d’ output) keeps increasing stably when you repeat the same operation, it should be have memory leak.
2, The RSS is just for your reference, it can’t used as the factor to detect memory leak.
3, although you call ‘free’ or ‘delete’, the virtual memory may not shrink immediately.
4, the same new operation may mapped to different [anon] virtual memory space. Here 1M was alloated to
000000001b56a000 and
00002ac25a77c000.
000000001b56a000
1156 12 12 rw---
[ anon ]
00002ac25a77c000
1040 16 16 rw---
[ anon ]
Test Code:
Program output:
pmap -d output:
pmap -d conclusion:
1, mapped and writeable/private can reflect the memory variation.
2, delete or free may not decrease mapped or writeable/private immediately.
pmap -x output:
pmap -x conclusion:
1, although you used new(step 3), the OS didn't commit the memory page until you read (STEP5)or write(STEP4) that memory space.
pmap -x:
2, the new memory operation maybe happened on different Address range. like the first 1M allcation at
00002ac25a77c000, but the 2nd 1M allcation happened at 000000001b56a000
Final pmap -d:
Final pmap -x
1, if the virtual memory (VIRT) or writeable/private (‘pmap –d’ output) keeps increasing stably when you repeat the same operation, it should be have memory leak.
2, The RSS is just for your reference, it can’t used as the factor to detect memory leak.
3, although you call ‘free’ or ‘delete’, the virtual memory may not shrink immediately.
4, the same new operation may mapped to different [anon] virtual memory space. Here 1M was alloated to
000000001b56a000 and
00002ac25a77c000.
000000001b56a000
1156 12 12 rw---
[ anon ]
00002ac25a77c000
1040 16 16 rw---
[ anon ]
Test Code:
#include "stdio.h" int global_i_init=0; static int static_global_j=11; int global_k; int main () { int tmp; printf ("global_i_init: 0x%lx\n",&global_i_init ); printf ("global_k non_init : 0x%lx\n",&global_k ); printf ("static_global_j : 0x%lx\n",&static_global_j ); printf ("stack i : 0x%lx\n",&tmp ); getchar (); // step2 char *x= new char[100*1024]; printf ("data allocate 100k @0x%lx\n", x); getchar(); // step3 char *x2= new char[1024*1024]; printf ("data allocate 1M i@0x%lx\n", x2); getchar(); // step4 printf ("data write at x2[1024*1024-1] "); x2[1024*1024-1]=0; getchar(); // step5 printf ("data read at x2 "); int j; for (int i=0;i<1024*1024; i++) j=x2[i]; getchar (); // step6 printf ("delete x2"); delete x2; getchar (); //step 7 printf ("delete x"); delete x; getchar(); //step8 x2= new char[1024*1024]; printf ("data allocate 1M i@0x%lx\n", x2); getchar (); }
Program output:
ATCA48-0-0-1:/root-# ./a.out global_i_init: 0x500cc0 global_k non_init : 0x500cc4 static_global_j : 0x500cb8 stack i : 0x7fff0120ab5c data allocate 100k @0x1b56a010 data allocate 1M i@0x2ac25a77f010 data write at x2[1024*1024-1] data read at x2 delete x2 delete x data allocate 1M i@0x1b56a010
pmap -d output:
mapped | writeable/private: | shared | ||
STEP 1 | init | 19616K | 236K | 0 |
STEP 2 | new 100k | 19848K | 468K | 0 |
STEP 3 | new 1M | 20876K | 1496K | 0 |
STEP 4 | write 1 byte | 20876K | 1496K | 0 |
STEP 5 | read 1M | 20876K | 1496K | 0 |
STEP 6 | delete 1M | 19848K | 468K | 0 |
STEP 7 | delete 100k | 19848K | 468K | 0 |
STEP 8 | new 1M | 20772K | 1392K | 0 |
1, mapped and writeable/private can reflect the memory variation.
2, delete or free may not decrease mapped or writeable/private immediately.
pmap -x output:
Total kbytes | RSS | Dirty | ||
STEP 1 | init | 19616 | 912 | 124 |
STEP 2 | new 100k | 19848 | 976 | 140 |
STEP 3 | new 1M | 20876 | 980 | 144 |
STEP 4 | write 1 byte | 20876 | 984 | 148 |
STEP 5 | read 1M | 20876 | 2004 | 148 |
STEP 6 | delete 1M | 19848 | 976 | 140 |
STEP 7 | delete 100k | 19848 | 980 | 140 |
STEP 8 | new 1M | 20772 | 984 | 144 |
Address | kbytes | RSS | Dirty | ||
STEP 1 | init | ||||
STEP 2 | new 100k | 000000001b56a000 | 232 | 8 | 8 |
STEP 3 | new 1M | 000000001b56a000 | 232 | 8 | 8 |
STEP 4 | write 1 byte | 000000001b56a000 | 232 | 8 | 8 |
STEP 5 | read 1M | 000000001b56a000 | 232 | 8 | 8 |
STEP 6 | delete 1M | 000000001b56a000 | 232 | 8 | 8 |
STEP 7 | delete 100k | 000000001b56a000 | 232 | 8 | 8 |
STEP 8 | new 1M | 000000001b56a000 | 1156 | 12 | 12 |
Address | kbytes | RSS | Dirty | ||
STEP 1 | init | 00002ac25a77c000 | 12 | 12 | 12 |
STEP 2 | new 100k | 00002ac25a77c000 | 12 | 12 | 12 |
STEP 3 | new 1M | 00002ac25a77c000 | 1040 | 16 | 16 |
STEP 4 | write 1 byte | 00002ac25a77c000 | 1040 | 20 | 20 |
STEP 5 | read 1M | 00002ac25a77c000 | 1040 | 1040 | 20 |
STEP 6 | delete 1M | 00002ac25a77c000 | 12 | 12 | 12 |
STEP 7 | delete 100k | 00002ac25a77c000 | 12 | 12 | 12 |
STEP 8 | new 1M | 00002ac25a77c000 | 12 | 12 | 12 |
1, although you used new(step 3), the OS didn't commit the memory page until you read (STEP5)or write(STEP4) that memory space.
pmap -x:
2, the new memory operation maybe happened on different Address range. like the first 1M allcation at
00002ac25a77c000, but the 2nd 1M allcation happened at 000000001b56a000
Final pmap -d:
Address Kbytes Mode Offset Device Mapping 0000000000400000 4 r-x-- 0000000000000000 008:00001 a.out 0000000000500000 4 rw--- 0000000000000000 008:00001 a.out 000000001b56a000 1156 rw--- 000000001b56a000 000:00000 [ anon ] 0000003677000000 112 r-x-- 0000000000000000 008:00001 ld-2.5.so 000000367721c000 4 r---- 000000000001c000 008:00001 ld-2.5.so 000000367721d000 4 rw--- 000000000001d000 008:00001 ld-2.5.so 0000003677400000 1336 r-x-- 0000000000000000 008:00001 libc-2.5.so 000000367754e000 2048 ----- 000000000014e000 008:00001 libc-2.5.so 000000367774e000 16 r---- 000000000014e000 008:00001 libc-2.5.so 0000003677752000 4 rw--- 0000000000152000 008:00001 libc-2.5.so 0000003677753000 20 rw--- 0000003677753000 000:00000 [ anon ] 0000003677c00000 520 r-x-- 0000000000000000 008:00001 libm-2.5.so 0000003677c82000 2044 ----- 0000000000082000 008:00001 libm-2.5.so 0000003677e81000 4 r---- 0000000000081000 008:00001 libm-2.5.so 0000003677e82000 4 rw--- 0000000000082000 008:00001 libm-2.5.so 0000003678c00000 52 r-x-- 0000000000000000 008:00001 libgcc_s-4.1.2-20080825.so.1 0000003678c0d000 2048 ----- 000000000000d000 008:00001 libgcc_s-4.1.2-20080825.so.1 0000003678e0d000 4 rw--- 000000000000d000 008:00001 libgcc_s-4.1.2-20080825.so.1 0000003679400000 920 r-x-- 0000000000000000 008:00001 libstdc++.so.6.0.8 00000036794e6000 2044 ----- 00000000000e6000 008:00001 libstdc++.so.6.0.8 00000036796e5000 24 r---- 00000000000e5000 008:00001 libstdc++.so.6.0.8 00000036796eb000 12 rw--- 00000000000eb000 008:00001 libstdc++.so.6.0.8 00000036796ee000 72 rw--- 00000036796ee000 000:00000 [ anon ] 00002ac25a76f000 16 rw--- 00002ac25a76f000 000:00000 [ anon ] 00002ac25a77c000 12 rw--- 00002ac25a77c000 000:00000 [ anon ] 00007fff011f8000 84 rw--- 00007ffffffe9000 000:00000 [ stack ] 00007fff013c2000 12 r-x-- 00007fff013c2000 000:00000 [ anon ] ffffffffff600000 8192 ----- 0000000000000000 000:00000 [ anon ] mapped: 20772K writeable/private: 1392K shared: 0K
Final pmap -x
Address Kbytes RSS Dirty Mode Mapping 0000000000400000 4 4 0 r-x-- a.out 0000000000500000 4 4 4 rw--- a.out 000000001b56a000 1156 12 12 rw--- [ anon ] 0000003677000000 112 96 0 r-x-- ld-2.5.so 000000367721c000 4 4 4 r---- ld-2.5.so 000000367721d000 4 4 4 rw--- ld-2.5.so 0000003677400000 1336 284 0 r-x-- libc-2.5.so 000000367754e000 2048 0 0 ----- libc-2.5.so 000000367774e000 16 16 8 r---- libc-2.5.so 0000003677752000 4 4 4 rw--- libc-2.5.so 0000003677753000 20 16 16 rw--- [ anon ] 0000003677c00000 520 20 0 r-x-- libm-2.5.so 0000003677c82000 2044 0 0 ----- libm-2.5.so 0000003677e81000 4 4 4 r---- libm-2.5.so 0000003677e82000 4 4 4 rw--- libm-2.5.so 0000003678c00000 52 16 0 r-x-- libgcc_s-4.1.2-20080825.so.1 0000003678c0d000 2048 0 0 ----- libgcc_s-4.1.2-20080825.so.1 0000003678e0d000 4 4 4 rw--- libgcc_s-4.1.2-20080825.so.1 0000003679400000 920 404 0 r-x-- libstdc++.so.6.0.8 00000036794e6000 2044 0 0 ----- libstdc++.so.6.0.8 00000036796e5000 24 24 20 r---- libstdc++.so.6.0.8 00000036796eb000 12 12 12 rw--- libstdc++.so.6.0.8 00000036796ee000 72 8 8 rw--- [ anon ] 00002ac25a76f000 16 16 16 rw--- [ anon ] 00002ac25a77c000 12 12 12 rw--- [ anon ] 00007fff011f8000 84 12 12 rw--- [ stack ] 00007fff013c2000 12 4 0 r-x-- [ anon ] ffffffffff600000 8192 0 0 ----- [ anon ] ---------------- ------ ------ ------ total kB 20772 984 144
相关文章推荐
- Howto find native code memory leak in Android
- How to Find A Memory Leak
- Howto find native code memory leak in Android
- How to debug native memory leak in anroid
- How To Find The Best Memory Foam Mattress Topper?
- Using the Kernel Debugger to Find a Kernel-Mode Memory Leak
- How to detect memory leak issue
- Umdhtools.exe: How to Use Umdh.exe to Find Memory Leaks
- How To Find Where The Memory Is Growing For A Process (Doc ID 822527.1)
- When is a Leak not a Leak? Using Heapshot Analysis to Find Undesirable Memory Growth
- Memo: How to use UMDH to detect memory leak
- How to use umdh to check Windows memory leak
- how to debug memory-leak
- C++ shared memory leak, how to clear shared memory?
- How to use windbg to detect memory leak
- When is a Leak not a Leak? Using Heapshot Analysis to Find Undesirable Memory Growth
- How to handle android could not find adb.exe
- How to find per-process I/O statistics on Linux
- How to detect and avoid memory and resources leaks in .NET applications()
- How to Find Maclean Liu?