valgrind检查内存泄露
#valgrind ./程序
内存泄漏问题,我们有memcheck工具来检查。很爽。但是有时候memcheck工具查了没泄漏,程序一跑,内存还是狂飙。这又是什么问题。。。
其实memcheck检查的内存泄漏只是狭义的内存泄漏,或者说是严格的内存泄漏,也就是说,在程序运行的生命周期内,这部分内存你是彻底释放不了了,即,你失去了这些地址。
其实还有第二种类型的内存泄漏,就是,长期闲置的内存堆积。这部分内存虽然你还保存了地址,想要释放的时候还是能释放。关键就是你忘了释放。。。杯具啊。这种问题memcheck就不给力了。这就引出了第二个内存工具valgrind –tool=massif。
会产生massif.out.****的文件,然后使用
# ms_print massif.out.*** >massif.log
massif 可以的帮我们发现很多问题,比如现实中总是遇到一些内存一直上涨,可以就是没有memory leaker的情况, 其实这样的情况并不奇怪,非常容易发生,比如每次循环的时候你并没有把上次的内存释放,同时不断在后面添加更多的内容,这显然不会有memory leaker,倒是到了一定的程度,自然会发生bad alloc的问题。对于这样的问题massif就可以大显身手,比较一下两个内存的切片,增加的部分自然就发现了。
官方主页教程:http://valgrind.org/docs/manual/ms-manual.html
先看一个图是分析firefox内存使用的:
安装massif-visualizer
massif-visualizer是ubuntu下的图形化分析工具
http://get.ubuntusoft.com/app/massif-visualizer
项目主页:
https://projects.kde.org/projects/extragear/sdk/massif-visualizer
massif-visualizer下载:
http://tel.mirrors.163.com/ubuntu/pool/universe/m/massif-visualizer/
软件包详细信息
:
http://packages.ubuntu.com/massif-visualizer
安装massif-visualizer:
------------------------------------------------------------------------------------
官方示例代码:
#include <stdlib.h> void g(void){ malloc(4000); } void f(void){ malloc(2000); g(); } int main(void){ int i; int* a[10]; for(i = 0; i < 10; i++){ a[i] = malloc(1000); } f(); g(); for(i = 0; i < 10; i++){ free(a[i]); } return 0; }# cc -o test test.c
Why is most of the graph empty, with only a couple of bars at the veryend? By default, Massif uses "instructions executed" as the unit of time.For very short-run programs such as the example, most of the executedinstructions involve the loading and dynamic linking of the program. Theexecution of main
(and thus the heapallocations) only occur at the very end. For a short-running program likethis, we can use the--time-unit=B
optionto specify that we want the time unit to instead be the number of bytesallocated/deallocated on the heap and stack(s).
If we re-run the program under Massif with this option, and thenre-run ms_print, we get this more useful graph:
在massif-visualizer下看图形化的:massif.out.4144
在massif-visualizer下看图形化的:massif.out.4164
再看这个C++程序:
#include <stdlib.h> #include <stdio.h> int *fa() { int *p=(int*)malloc(10000); return p; } int *fb(int *p) { delete p; } int main(void) { printf("ok\n"); printf("really ok?\n"); int *vec[10000]; for(int i=0;i<10000;i++) { vec[i]=fa(); } for(int i=0;i<10000;i++) { fb(vec[i]); } return 0; }
监控nginx,redis,memcached
# valgrind --tool=massif /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
# valgrind --tool=massif /usr/local/memcached/bin/memcached -d -m 64 -uroot -l 0.0.0.0 -p 11211 -c 1024
# valgrind --tool=massif /usr/redis-2.8.1/src/redis-server
redis:
memcached:
nginx:
安装一个插件可以看到函数调用关系:
firefox:
-----------------------------------------------------------------------------
非常好的使用实例:
http://blog.mozilla.org/nnethercote/2010/12/09/memory-profiling-firefox-with-massif/
Here’s the command line I used:
valgrind --smc-check=all --trace-children=yes --tool=massif --pages-as-heap=yes \ --detailed-freq=1000000 optg64/dist/bin/firefox -P cad20 -no-remote
Here’s what that means:
--smc-check=all
tells Valgrind that the program may use self-modifying code (or, in Firefox’s case, overwrite dynamically generated code).--trace-children
tells Valgrind to trace into child processes exec’d by the program. This is necessary because optg64/dist/bin/firefox is a wrapper script.--tool=massif
tells Valgrind to run Massif.--pages-as-heap=yes
tells Massif to profile allocations of all memory at the page level, rather than just profiling the heap (ie. memory allocated via malloc/new). This is important because the heap is less than half of Firefox’s memory consumption.--detailed-freq=1000000
tells Massif to do detailed snapshots (which are more informative but more costly) only every 1,000,000th snapshot, which is less often than the default of every 10th snapshot. This makes it run a bit faster. This is fine because Massif always takes a detailed snapshot at the peak memory consumption point, and that’s the one I’m interested in.optg64/
is the name of my build directory.-P cad20
tells Firefox to use a particular profile that I set up appropriately.-no-remote
tells Firefox to start a new instance; this is necessary because I had a Firefox 3.6 process already running.ms_print massif.out.22722
更多参考:http://www.cs.washington.edu/education/courses/cse326/05wi/valgrind-doc/ms_main.html