技术刘

PTAM 中的内存泄露问题和修正

在编译和调试 PTAM 过程中发现一些可能引起内存泄露的问题,现将修改方法列出供参考。由于 PTAM 可能更多的只是一个实验代码,我也并没有仔细阅读过,因此问题可能远不止这些,如有发现问题或者修改不当之处,欢迎大家在后面留言讨论。

1、Keyframe 中的内存泄露修正:
1) 修改 Keyframe.h 文件,增加析构函数:

    ~KeyFrame();

2) 修改 Keyframe.cc 文件,增加析构函数:

KeyFrame::~KeyFrame() {
    if(pSBI != NULL)
        delete pSBI;
    
    pSBI = NULL;
}

2、MapPoint 中的内存泄露修正:
1) 修改 MapPoint.h 文件,增加析构函数:

    ~MapPoint();

2) 修改 MapPoint.cc 文件,加入头文件:

#include "TrackerData.h"
#include "MapMaker.h"

3) 修改 MapPoint.cc 文件,增加析构函数:

MapPoint::~MapPoint()
{
    if (pTData != NULL)
        delete pTData;
    if (pMMData != NULL)
        delete pMMData;
    
    pTData = NULL;
    pMMData = NULL;
}

3、Map 中的内存泄露修正:
1) 修改 Map.cc 文件,增加析构函数声明:

    ~Map();

2) 修改 Map.cc 文件,在顶部增加如下代码:

#include "KeyFrame.h"

3) 修改 Map.cc 文件,在 Reset 函数中增加如下代码:

    for(unsigned int i=0; i<vpKeyFrames.size(); i++) {
        delete vpKeyFrames[i];
    }
    vpKeyFrames.clear();

4) 修改 Map.cc 文件,增加析构函数内容:

Map::~Map()
{
    Reset();
}

4、Tracker 中的内存泄露修正:
1) 修改 Tracker.h 文件,增加析构函数:

     ~Tracker();

2) 修改 Tracker.cc 文件,增加析构函数:

Tracker::~Tracker()
{
    if(mpSBILastFrame) delete mpSBILastFrame;
    if(mpSBIThisFrame) delete mpSBIThisFrame;
    
    mpSBILastFrame=NULL;
    mpSBIThisFrame=NULL;
}

5、MapMaker 中的内存泄露修正:
在 MapMaker 中存在一个非常隐含的内存泄露,就是在 mvpKeyFrameQueue 添加关键帧后,其处理过程中为了保存给后面 BoundleAdjustAll 使用而没有删除关键帧,后续也没有回收这一段内存。因此我们需要一个 vector 保存下需要回收的内存数组:
1) 修改 MapMaker.h 文件,增加变量:

    std::vector mvpNeedToDeleteKeyFrame;  // Queue of keyframes from the tracker waiting to be processed

2) 修改 MapMaker.cc 文件,在 Reset() 函数中添加:

    for (int i=0; i

3) 修改 MapMaker.cc 文件,在 ~MapMaker() 析构函数中添加:

    RequestReset();
    while(!ResetDone()) {
        usleep(10);
    }

附注:最外层的释放顺序
由于 MapMaker 里面包含 mMap 的 Reset 操作,因此最外层结束时释放顺序需要注意下,我这里是这样写的:

        delete mMapMaker;
        delete mCamera;
        delete mMap;
        delete mTracker;