DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

在学习FPS3000人脸关键点定位算法时,发现github上的源码,存在大量的内存泄漏问题,在训练的时发现内存一直在增长,测试的时候也存在内存无法彻底释放的问题。

一直以为是存放模型参数vector<class>结构的问题, 采用以下方法手动释放,仍然无法解决问题。

 

  1.  
    vector<class> regressors_;
  2.  
    regressors_.clear();
  3.  
    std::vector<Regressor>().swap(regressors_);

经过仔细检查发现,有好几个类没有析构函数,于是就添加了CascadeRegressor::~CascadeRegressor();Regressor::~Regressor();RandomForest::~RandomForest();Node::~Node();由于class类不支持手动释放,只能在析构函数里自动释放内存。而且还发现有很多new()和#define Malloc(type,n) (type *)malloc((n)*sizeof(type))手动方式分配的内存没有手动释放。

 

那我是怎么发现的呢?方法如下:

一、在VS2013的DeBug模式下在代码中添加如下代码:

 

  1.  
    #include <stdlib.h>
  2.  
    #include <crtdbg.h>
  3.  
     
  4.  
     
  5.  
    #ifdef _DEBUG
  6.  
    #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
  7.  
    #endif
  8.  
     
  9.  
    void EnableMemLeakCheck()
  10.  
    {
  11.  
    int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  12.  
    tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
  13.  
    _CrtSetDbgFlag(tmpFlag);
  14.  
    }
  15.  
     
  16.  
    using namespace std;
  17.  
    int main()
  18.  
    {
  19.  
    EnableMemLeakCheck();
  20.  
    //_CrtSetBreakAlloc(3558059);
  21.  
    此处添加自己的代码
  22.  
    }

 

二、然后编译执行程序,如果代码中存在内存泄漏,则在程序终止时,输出端口看到如下内容:

 

  1.  
    线程 0x1b24 已退出,返回值为 0 (0x0)。
  2.  
    Detected memory leaks!
  3.  
    Dumping objects ->
  4.  
    {3558059} normal block at 0x0000000007F11480, 62544 bytes long.
  5.  
    Data: < y W] > CC AD FF AD AA 1B A2 BE 79 9E 57 5D E2 8E FE BE
  6.  
    {3558049} normal block at 0x0000000007CB98F0, 88 bytes long.
  7.  
    Data: < > 0C 00 00 00 CD CD CD CD CD CD CD CD CD CD CD CD
  8.  
    {3558025} normal block at 0x0000000007EF1A90, 62544 bytes long.
  9.  
    Data: < FR > .u ?> E2 CB 46 52 DD 11 E1 3E CB C9 93 2E 75 BE 00 3F
  10.  
    {3558015} normal block at 0x0000000007CBA170, 88 bytes long.
  11.  
    Data: < > 0C 00 00 00 CD CD CD CD CD CD CD CD CD CD CD CD

 

从以上log中可以看到3558059的地方存在内存泄漏,那我们可以把main()函数中的这个函数去掉注释,

 

 

  1.  
    int main()
  2.  
    {
  3.  
    EnableMemLeakCheck();
  4.  
    _CrtSetBreakAlloc(3558059);
  5.  
    此处添加自己的代码
  6.  
    }



 

然后重新编译并执行程序,代码就会run到内存泄漏的地方就停下来。

此法对于查找内存泄漏非常方便。

posted on 2018-08-06 10:40  DoubleLi  阅读(593)  评论(0编辑  收藏  举报