From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

DAQmx Apparent Memory Leak

Solved!
Go to solution

Looking to get fresh eyes on an annoying problem. Recently our team was seeing an apparent memory leak (RAM usage increasing by about 4 kB/s, when tracked with Windows Task Manager) in a large top-level VI, causing it to crash about once a week. We tracked it down to a DAQmx task in a While loop (code snippet attached; we've verified this generates the apparent memory leak behavior on 3 different systems in our lab). With every execution of the loop, we make a DAQmx task that checks one DIO, looking for a simple ON/OFF trigger from an external system, and finally we clear the task and move on. There's a 5 ms delay in the loop so that it won't eat up CPU cycles, but we keep the delay small-ish so that our system is responsive to this external signal. We chose to implement this regular polling of the DIO because our particular DAQ (PCI 611x) does not support digital state change detection.

 

We've already done enough debugging to guess that the memory leak is tied to repeated creation/clearing of the DAQmx task. The issue disappears if we use a "persistent" DAQmx task--i.e., call "DAQmx Create Channel" once and then keep referencing the same DAQmx task with each execution of the loop.

 

My questions are (1) WHY do we see this behavior, and (2) is it documented anywhere? I understand that creating and clearing a DAQmx task every 5 ms is a rather inefficient use of system resources, but why exactly would it lead to memory problems? To me it looks like the DAQmx VIs are the culprit, but perhaps I'm overlooking an error on my part. I've seen related posts on the forums (here and  here), but nothing that is a real close match for my scenario.

 

Much thanks in advance! In case it matters, we're running LabVIEW 2017 on Windows 7 and Windows 10 systems.

0 Kudos
Message 1 of 35
(4,689 Views)

This thread may offer some clues, but I have seen this behavior before with AI tasks. I gave up a bit, and decided to reuse tasks where possible. Is your system 32bit? I found it was worse with 32bit systems. You can try inserting some primitives, like below and see if they help.

 

Snap12.png

 

mcduff

Message 2 of 35
(4,667 Views)

No definitive insight on the "why" and I can't look at the LV2017 code b/c I'm at LV2016.

 

As you've mentioned, creating and clearing tasks in a loop is inefficient and not recommended, *especially* when you're attempting to do so every 5 msec.   In practice, I expect your loop doesn't iterate at 200 Hz because the time to create the task, read the DI, and clear the task probably consumes quite a bit more than 5 msec.

 

In contrast, the method where you create before the loop, only read inside the loop, and clear after the loop would likely iterate at many kHz if you didn't have the 5 msec delay in there.  Not only is it a general good practice, it prevents your memory problem, reduces your CPU usage, *and* lets you poll more frequently to be more responsive to this external signal.  Win, win, win, win.

 

Maybe someone else can comment with detailed knowledge about *why* memory leaks when creating and clearing DAQmx tasks repeatedly and that will satisfy your curiosity (mine too).  I have a vague recollection of seeing a related discussion here before, but can't vouch for whether it was strictly similar and relevant. 

    The thing I want to emphasize though is that you *have* indeed found the *solution* already.  Even if the leak is tied to a specific version range of DAQmx (I have no idea whether this is true, just making a point), it'd still be better to solve it with the right programming practice than by installing a driver version that responds better to a bad practice.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
Message 3 of 35
(4,662 Views)

@mcduff: Thanks for the link; very helpful stuff.

 

@Kevin: Good points, especially on the expected execution time (5 ms) vs. actual execution time (TBD). To me there is something "clean" about creating/clearing a task when I need it with every loop iteration, because it localizes all the relevant resources to just that one section of code. But if that causes degradation in performance, then it trumps any subjective concept I have of "clean." You're right that this question is already solved in a practical sense, but I'll leave it open for a bit to see if any other responses come in.

0 Kudos
Message 4 of 35
(4,650 Views)

@hwilterdink wrote:

Looking to get fresh eyes on an annoying problem. Recently our team was seeing an apparent memory leak (RAM usage increasing by about 4 kB/s, when tracked with Windows Task Manager) in a large top-level VI, causing it to crash about once a week. We tracked it down to a DAQmx task in a While loop (code snippet attached; we've verified this generates the apparent memory leak behavior on 3 different systems in our lab). With every execution of the loop, we make a DAQmx task that checks one DIO, looking for a simple ON/OFF trigger from an external system, and finally we clear the task and move on. There's a 5 ms delay in the loop so that it won't eat up CPU cycles, but we keep the delay small-ish so that our system is responsive to this external signal. We chose to implement this regular polling of the DIO because our particular DAQ (PCI 611x) does not support digital state change detection.

 

We've already done enough debugging to guess that the memory leak is tied to repeated creation/clearing of the DAQmx task. The issue disappears if we use a "persistent" DAQmx task--i.e., call "DAQmx Create Channel" once and then keep referencing the same DAQmx task with each execution of the loop.

 

My questions are (1) WHY do we see this behavior, and (2) is it documented anywhere? I understand that creating and clearing a DAQmx task every 5 ms is a rather inefficient use of system resources, but why exactly would it lead to memory problems? To me it looks like the DAQmx VIs are the culprit, but perhaps I'm overlooking an error on my part. I've seen related posts on the forums (here and  here), but nothing that is a real close match for my scenario.

 

Much thanks in advance! In case it matters, we're running LabVIEW 2017 on Windows 7 and Windows 10 systems.


I can offer advice on both cases.

 

The DAQmx state transition diagram in the help file is not exactly accurate.  They do stuff to optimize the state transitions that will potentially leak memory in rare instances.

 

Next. I will say it once again.  DAQmx tasks should never be created more than once!  Preferably during development! And never more than once per application instance.  Save your task. Use it .  And if you have specific reasons why you want to do it at run time...I can tell you why that is not needed and how LabVIEW did that for you... and where that got put.


"Should be" isn't "Is" -Jay
Message 5 of 35
(4,641 Views)

I'd wager DAQmx tasks works like .net handles and similar things, you create a pointer of sorts and this small memory is hard to reuse or possibly the system doesn't realize it's released. Thus you'll 'leak' 4 bytes with each call.

I had a program in which i used ActiveX to make a plugin and it looped through lots of objects and stuff. Apparently you can only open 1 millions refs before LV crashes. 😄
By caching the lookups i could reduce the Creation and looping of these refs, gaining performance and scale.
So, as already mentioned, try to only create the tasks in some Init state (which could be called rarely, basically at start and after a setting change)

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 6 of 35
(4,619 Views)

Creating a new task (which is time consuming for the processor) is not the way to go. Your causing a memory leak by opening task each iteration, and not closing the memory space reference to them.  I'm sure the DAQmx VI help mention that when using Open New Task VI.  Open a (or all) task once, do your iteration, then close a (or all) task.

 

Rich J

0 Kudos
Message 7 of 35
(4,597 Views)
Solution
Accepted by topic author hwilterdink

Hi all,

 

I've been working with Harrison on this issue through NI Support. We were able to reproduce the memory leak when spinning an infinite loop in which we create a task, read from it once, and close it.

 

As everyone has mentioned, DAQmx is not optimized for this usage and using a single task is the workaround and recommended usage for all applications.

 

That being said, I have filed a corrective action report with our LabVIEW R&D engineers so they are aware of the leak. I cannot promise that this will be fixed soon, but our internal resources are now aware of the issue.

 

Thanks!

 

Duncan Waldrop

Applications Engineer

National Instruments

Message 8 of 35
(4,566 Views)

@Yamaeda wrote:

 

I had a program in which i used ActiveX to make a plugin and it looped through lots of objects and stuff. Apparently you can only open 1 millions refs before LV crashes. 😄


There is a 2^20 element limit on a lot of references in LabVIEW. I tested a lot of hardware and most driver references would just report some sort of memory error at that point but I'm not all surprised that ActiveX references didn't behave as nicely as more native reference data types.

 

Edit: Also, what version (year/patch) is OP using? I believe CAR 657155 was fixed in a few patches which dealt with LabVIEW not closing/reusing DAQmx references that would eventually lead to a crash.

Matt J | National Instruments | CLA
Message 9 of 35
(4,546 Views)

@Matt: At LabVIEW startup under Help >> About LabVIEW... the version is listed as 17.0f2 (32-bit). Also regarding mcduff's earlier question, we're using LabVIEW 32-bit, and I think it's running on both 32-bit and 64-bit systems.

0 Kudos
Message 10 of 35
(4,537 Views)