Monday, July 7, 2008

Insidious Memory Leaks, Part 1

Memory leaks are the bane of any software application that must run continuously for long periods of time. The common causes -- building arrays or concatenating strings within loops -- are relatively easy to spot for most developers. However, leaks can sometimes creep into applications in seemingly harmless ways. Consider the following code snippet, developed by a local integrator, that was extracted from an instrument polling loop that runs in parallel to a main application.It looked innocuous enough to me... Sure, why not use a notifier to stop the loop when the main application is stopped? It seemed to run without problems under Windows. However, when it was downloaded to a PXI-RT target, it leaked like a screen door on a submarine. The fix was simple enough: put the Obtain Notifier outside of the loop and pass in the refnum through a tunnel. You would think that Obtain Notifier would simply return a pointer to the existing notifier, but apparently things work differently enough in RT to cause headaches. I haven't tried it yet, but I bet the same (mis)behavior is evident when obtaining refnums from other synchronization tools.

The moral of the story is a simple one you see over and over again: if a code element doesn't need to be in a loop, then don't put it there. Duh.

7 comments:

Unknown said...

I think the shown code doesn't have a memory leak if you use 'force destroy' on the close queue primitive.

This will destroy all instances of the named queue.

Ton

Anonymous said...

Bob: Welcome to the LabVIEW blogosphere! I enjoyed your article and look forward to reading more from you, soon :) And, thanks for the link to Thinking in G. I'm happy to return the favor.

Ton: The "force destroy" is (probably) counter to how this code works, as it is using a named queue (which is typically created once and accessed many times as a sort of messaging global). If you force destroy, you could inadvertently delete a notification.

nancy said...

... and yes, Queues work just as notifiers do. My understanding is that semaphores/rendezvous work differently. The "Destroy" actually destroys the object. Notice the the naming on queues/notifiers it is "Obtain/Release" thus providing us a wee little clue as to the different behavior.

Great to have your blog up! I'll look forward to your articles and pass the info on.

ThinkThankful said...

I wish I could say anything intelligent about LabVIEW but instead I'll just say congrats on starting your blog!

Christina said...

Welcome to the LabVIEW blog family, Bob! I look forward to reading future insights.

However, I do have a concern about calling this situation a "memory leak." I posted on my blog about it.

Anonymous said...

Great to see your blog up and running Bob, and a nice article about memory lakes :)

You might want to add your blog to the LabVIEW blog list here: http://forums.lavag.org/blog.html

Mike Battaglia said...

I have found a nightmare of a memory leak as well. If you continue to open DAQ tasks without clearing them, as in a while loop, and save to a shift register, the code leaks like a screen door.