上次,我們提到利用google gperftools定位程序cpu使用性能問題,這次利用同樣的工具的heap checker的功能對程序進行內存泄漏的定位。安裝請看之前的文章:
#include <iostream>
#include <vector>
using namespace std;
extern "C" {
#include <string.h>
}
class MyClass {
private:
char* str;
public:
MyClass(const char* s) {
cout<<"construct MyClass\n";
str = new char[strlen(s)];
strcpy(str, s);
}
~MyClass() {
cout<<"~MyClass\n";
//delete str;//我們把這一行註釋掉
}
MyClass(const MyClass& mc) {
cout<<"copy MyClass\n";
delete str;
str = new char[strlen(mc.str)];
strcpy(str, mc.str);
}
MyClass& operator= (const MyClass& mc) {
cout<<"operator=(&)\n";
if(this != &mc) {
delete str;
str = new char[strlen(mc.str)];
strcpy(str, mc.str);
}
}
friend ostream& operator << (ostream& os, MyClass& mc) {
os<<mc.str;
return os;
}
MyClass& operator = (MyClass&& mc) {
cout<<"operator = &&\n";
if(this != &mc) {
this->str = mc.str;
mc.str = NULL;
}
}
MyClass(MyClass&& mc) {
cout<<"MyClass &&\n";
this->str = mc.str;
mc.str = NULL;
}
};
vector<MyClass> makeMcVec() {
vector<MyClass> v;
v.reserve(3);
v.push_back(MyClass("Hello World"));
v.push_back(MyClass("\n"));
return v;
}
vector<MyClass> makeMcVec1() {
vector<MyClass> v;
v.reserve(3);
MyClass a("Hello World");
MyClass b("\n");
v.push_back(move(a));
v.push_back(move(b));
return v;
}
int main() {
vector<MyClass> mvVec = makeMcVec1();
cout<<"after makeMcVec\n";
for(auto it = mvVec.begin(); it != mvVec.end(); it++) {
cout<<*it;
}
return 0;
}
我們拿之前一個右值引用的例子,把析構函數裏面的delete去註釋掉。
然後進行以下命令:
g++ -g -o MyClass MyClass.cpp -std=c++11 -ltcmalloc //鏈接tcmalloc
export PPROF_PATH=/usr/local/bin/pprof
env HEAPCHECK=normal /home/oujiangping/project/blog/MyClass
結果如下:
WARNING: Perftools heap leak checker is active -- Performance may suffer
construct MyClass
construct MyClass
MyClass &&
MyClass &&
~MyClass
~MyClass
after makeMcVec
Hello World
~MyClass
~MyClass
Have memory regions w/o callers: might report false leaks
Leak check _main_ detected leaks of 12 bytes in 2 objects
The 2 largest leaks:
Using local file /home/oujiangping/project/blog/MyClass.
Leak of 11 bytes in 1 objects allocated from:
@ 401053 MyClass::MyClass
@ 400e07 makeMcVec1
@ 400eef main
@ 7f632931d830 __libc_start_main
@ 400bf9 _start
Leak of 1 bytes in 1 objects allocated from:
@ 401053 MyClass::MyClass
@ 400e18 makeMcVec1
@ 400eef main
@ 7f632931d830 __libc_start_main
@ 400bf9 _start
If the preceding stack traces are not enough to find the leaks, try running THIS shell command:
pprof /home/oujiangping/project/blog/MyClass "/tmp/MyClass.15222._main_-end.heap" --inuse_objects --lines --heapcheck --edgefraction=1e-10 --nodefraction=1e-10 --gv
If you are still puzzled about why the leaks are there, try rerunning this program with HEAP_CHECK_TEST_POINTER_ALIGNMENT=1 and/or with HEAP_CHECK_MAX_POINTER_OFFSET=-1
If the leak report occurs in a small fraction of runs, try running with TCMALLOC_MAX_FREE_QUEUE_SIZE of few hundred MB or with TCMALLOC_RECLAIM_MEMORY=false, it mi
Exiting with error code (instead of crashing) because of whole-program memory leaks
函數指出了makeVec1中調用MyClass存在兩次內存泄漏分別是11字節和1字節,其實就是使用“Hello world”和“\n”創建的字符串,可以看到構造函數中有一個new語句,沒有釋放,在析構函數中delete就好了。