ORB_SLAM2 icon indicating copy to clipboard operation
ORB_SLAM2 copied to clipboard

Memory leak caused by MapPoint and KeyFrame erase.

Open highlightz opened this issue 6 years ago • 16 comments

When erasing a MapPoint pointer or a KeyFrame pointer from the Map, the code just delete the pointer of queue, and no memory releasing operation is performed. This is a problem when the machine has not enough memory. Is there a good way to handle this?

highlightz avatar Jan 12 '18 05:01 highlightz

Below shows the related code:

void Map::EraseMapPoint(MapPoint *pMP) {
    unique_lock<mutex> lock(mMutexMap);
    mspMapPoints.erase(pMP);

    // TODO: This only erase the pointer.
    // Delete the MapPoint
  }

  void Map::EraseKeyFrame(KeyFrame *pKF) {
    unique_lock<mutex> lock(mMutexMap);
    mspKeyFrames.erase(pKF);

    // TODO: This only erase the pointer.
    // Delete the MapPoint
  }

highlightz avatar Jan 12 '18 05:01 highlightz

same question

xiaod17 avatar Jan 17 '18 07:01 xiaod17

In fact, I have tried to replace MapPoint* with std::shared_ptr<MapPoint>, and replace KeyFrame* with std::shared_ptr<KeyFrame>, in order to automatically manage the memory. But this makes no big difference. The destruct function of KeyFrame is never called when a KeyFrame is culled.

highlightz avatar Jan 18 '18 05:01 highlightz

I'm reading the code and trying to figure out how concurrency is handled in the system. I'm confused here, too. It seems the authors are aware of the resource leaking problem as indicated in the comments, but left it as is intentionally. Is there a reason to do this?

zc08 avatar Jan 21 '18 12:01 zc08

@highlightz I think cyclic references exist. MapPoint maintains a vector that points to KeyFrames where it is visible, and KeyFrame also maintains a list of MapPoints.

zc08 avatar Jan 22 '18 07:01 zc08

@zc08 Yeah, you are correct. Cyclic reference does exist. I've replace std::shared_ptr<KeyFrame> with std::weak_ptr<KeyFrame>, and this technology can handle cyclic reference.

highlightz avatar Jan 22 '18 10:01 highlightz

@highlightz so the std::weak_ptr is useful?

xiaod17 avatar Jan 22 '18 10:01 xiaod17

Not really, destructor of KeyFrame is still not called. This denotes that there'is still MapPoint associating with a Culled KeyFrame, which causes reference count of KeyFrame pointer never decreases to zero.

highlightz avatar Jan 22 '18 10:01 highlightz

I think in the program, there is somewhere one KeyPoint in a KeyFrame(aka. 2D observation), corresponds to at lease two MapPoints.

highlightz avatar Jan 22 '18 10:01 highlightz

The main KeyFrame and MapPoint is in the Map class, inside of a set container, and other references at some KeyFrame or MapPoint is pointing to its. If you want to remove the KeyFrame or MapPoint you can do it from Map, but if you do it without remove all the references in others class to the same instance you would have an access error.

richard-elvira avatar Jan 22 '18 10:01 richard-elvira

You are right, this is why I've tried to use C++ smart pointer to manage every MapPoint* and KeyFrame*.

highlightz avatar Jan 22 '18 11:01 highlightz

weak_ptr and sharded_ptr is time comsuming ,do you have any good ideal to remove the Memory leak caused by MapPoint and KeyFrame erase

lixiaohang avatar Mar 17 '18 09:03 lixiaohang

Did you guys solve this?

arifle avatar Oct 24 '18 08:10 arifle

I am trying to solve the same problem. Did anybody solve this?

GiuliaMarchesi avatar Apr 15 '20 06:04 GiuliaMarchesi

Hi @highlightz Did you solve this? Thanks

xzwang12345 avatar Jan 06 '21 09:01 xzwang12345

I just tried using shared_ptr to solve this problem, here.

fishmarch avatar Jul 12 '23 15:07 fishmarch