gperftools檢查內存泄漏

上次,我們提到利用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就好了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章