最近遇到一个bug,TensorRT3.0没有办法进行内存释放,这个官网也有提到,大意就是调用destory函数(内存销毁的函数),一片内存会被释放两次,然后代码就崩溃了.这个参考文献在这里:

(注意:bug产生的条件就是不停调用TensorRT,对其进行初始化,初始化结束后再销毁,反复操作,就能看到相应的内存泄漏)

问题描述:error tensorRT: terminate called after throwing an instance of \'nvinfer1::CudaError\' what(): std::exception Aborted (core dumped)]

参考:https://devtalk.nvidia.com/default/topic/1028517/tensorrt/tensorrt-3-0-1-ssdnormalizeplugin-destroy-fails/1

然后就将TensorRT3升级到了TensorRT4.0,然后发现destory是可以使用了,但是依然有内存泄漏的问题;现在还在找原因;

 

内存销毁注意事项:

1)delete掉一个void*类型的指针,导致没有调用到对象的析构函数,析构的所有清理工作都没有去执行从而导致内存的泄露; 
代码如下:

class   {
private:
    void* data;
    const int size;
    const char id;
public:
     (int sz, char c):size(sz), id(c){
    data = new char[size];
    cout << \" () \" << id << \" size = \" << size << endl;
    }
    ~ (){
    cout << \"~ () \" << id << endl;
    delete []data;
    }
};


紧接着使我们的main函数:

int main() {
 * a = new  (10, \'A\');// *指针指向一个 对象;
void* b = new  (20, \'B\');//void*指针指向一个 对象;
delete a;//执行delete,编译器自动调用析构函数;
delete b;//执行delete,编译器不会调用析构函数,导致data占用内存没有得到回收;

cout << \"Press any key to continue... ...\" << endl;
getchar();
return 0;
}


执行结果如下图: 

\"\"


 
从执行结果看到,并没有执行b指针(void*)所指对象的析构函数,所以delete一个void*的指针可能会造成内存上的泄露!
参考:https://blog.csdn.net/qq_18824491/article/details/78902636

2)new创建了一组对象数组,内存回收的时候却只调用了delete而非delete []来处理,导致只有对象数组的第一个对象的析构函数得到执行并回收了内存占用,数组的其他对象所占内存得不到回收,导致内存泄露; 
代码如下:

class  1
{
    int a;
    int b;
};

int main() {
 1* arry1 = new  1[100];//创建包含100个 1的对象数组arry1并返回数组首地址;
 1* arry2 = new  1[100];//创建包含100个 1的对象数组arry2并返回数组首地址;
delete []arry1;//回收了数组arry1里的所有对象动态创建时占用的内存空间;
delete  arry2;//回收了数组arry2里的第一个对象动态创建时占用的内存空间,导致其他99个对象的内存空间泄露;

cout << \"Press any key to continue... ...\" << endl;
getchar();
return 0;
}

参考:https://blog.csdn.net/qq_18824491/article/details/78902636

3)unique ptr的内存释放问题,例子代码:

void(*nvPluginDeleter)(INvPlugin*) { [](INvPlugin* ptr) {ptr->destroy(); } };
std::unique_ptr<INvPlugin, decltype(nvPluginDeleter)> m_plugin_ptr{ nullptr, 
nvPluginDeleter };
m_plugin_ptr.release();
m_plugin_ptr =  nullptr;

如果只是使用release只是转让了m_plugin_ptr的内存使用权,但是内存根本就没有释放掉;

正确的做法是这样的:

void(*nvPluginDeleter)(INvPlugin*) { [](INvPlugin* ptr) {ptr->destroy(); } };
std::unique_ptr<INvPlugin, decltype(nvPluginDeleter)> m_plugin_ptr{ nullptr, 
nvPluginDeleter };
m_plugin_ptr.reset();
m_plugin_ptr.release();
m_plugin_ptr =  nullptr;

加入了reset函数,unique ptr的指针就使用void(*nvPluginDeleter)(INvPlugin*) { [](INvPlugin* ptr) {ptr->destroy(); } };释放掉了内存;

4)如果vector中保存的unique ptr的指针指向的内存空间,则一定要进行循环释放,举例如下:

 std::vector<std::unique_ptr<INvPlugin, decltype(nvPluginDeleter)> > m_nvPlugins_plugin;
 if(!m_nvPlugins_plugin.empty()){
        for(int i = 0;i<m_nvPlugins_plugin.size();i++){
            m_nvPlugins_plugin.at(i).reset();
            m_nvPlugins_plugin.at(i).release();
            m_nvPlugins_plugin.at(i) =  nullptr;
        }
        m_nvPlugins_plugin.clear();
    }

 

收藏 打印