These memory leaks

Flame chart in VTune Profiler.
Process memory consumption chart. You would expect having a horizontal trend line to avoid going out of memory in the long run.
for ( ... )
{
MEMCHECK

// Your code to profile goes right here.

MEMCHECKREL // or yet another MEMCHECK for absolute measures.
}

// Dump to file.
MEMCHECK_DUMP("memlog.txt")
Process memory delta chart. You would not expect having all these peaks, or at least to have them followed by anti-peaks. That’s not what is happening here, in the highlighted window.

Lessons learned

Smart pointers

Make sure your pointers are smart enough. In our team, we are using a mix of OpenCascade plus VTK, where both libraries come up with their own implementations of smart pointers. VTK is arguably doing that surprisingly badly, as the methods you call from it often return naked pointers. It’s up to you to decide whether to take the ownership of those pointers or not. And then keep fingers crossed that your memory is gonna get cleaned up later on. Take care of using smart pointers whenever you can.

Oh-CAF

Everybody knows that smart pointers are nice and using them improves your karma. Much fewer people know about a few specific aspects of the OpenCascade library that could potentially cause memory leaks. OCAF is one of those things. Here is the problem: OCAF does not delete labels even if the corresponding object is destroyed. On the long run, you can easily end up having a graveyard of labels that you wouldn’t even notice without specific tools like dfbrowse.

Dead labels in OCAF document. They are all allocated from the heap memory but do not contain any attributes, i.e., real data.

RTFM and fancy C++

False-positive memory leaks could originate from allocators that are supposed to manage memory chunks from preallocated memory arena. We were using RapidJson lib whose allocators might consume quite some bytes and need careful cleanup. The source of memory leak here was the missing virtual destructor in the base class for RapidJson document. As a result, deleting an object through its base-type pointer left the derived objects as garbage in memory. Such a memory leak is hard to spot, but its contribution to the overall process memory was significant.

for ( auto aagIt = new asiAlgo_AAGRandomIterator(aag);
aagIt->More();
aagIt->Next() )
{
...
}

Conclusion

Hunting down memory leaks is quite a journey unless what you’re profiling is a simple independent main() function. After a while, I’m pretty convinced that there’s no any magic tool to really help you out in the memory leak detection business. What matters most is your common sense plus care and time. Still, I hope that the information given above would give someone a clue when memory becomes an issue.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store