LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Memory issue/leak using Register Event Callback

Hi everyone,

 

I encountered a memory leak in my VI (Labview 2016) using Register Event Callback. I created a user event that is triggered every time a signal is generated by a controller (3000 data points). Upon receiving these data points an event is triggered and the new signal is displayed on the front panel. This works beautifully (screenshot attached). 

The problem is the rapidly growing memory usage for Labview shown by the windows task manager - until it crashes. It seems the data I receive is not disposed and shoved into memory every time my VI receives a new signal. I read through dozens of forums and tried many suggestions but could not find a post that helped.

One reason could be that I only Unregister For Events once I stop the VI, but I want to have it running continuously so that does not happen. I tried to unregister the event inside the while loop and reinitialise it. But that unfortunately did not work since the event structure waits for the event I just unregistered. Best would be if I could dispose the received set of data after displaying it.

The main VI is MemoryFail, the VI OnDisplayPulseReady was provided by the controller manufacturer. Without the connected electronics, however, one won't be able to run it. Hopefully someone can still help me out to find the problem.

Cheers,

Thomas

 

0 Kudos
Message 1 of 10
(2,141 Views)

Not very surprising. Each refnum in LabVIEW is a small amount of memory refering to some kind of object. For your .Net refnums this is actually a small amount of LabVIEW refnum memory pointing to a .Net object that contains all the data for that object. So each and every event you receive is a PulseReadyEventArgs object holding all the data for your pulse. And to make things just a tiny little worse you also retrieve the sub Object with the data as a List.

 

Close these two refnums after you are done with them and your "memory leak" disappears like snow in the sun.

 

Also why are you actually copying the incoming PulseReadyEventArgs object into a newly created PulseReadyEventArgs object inside the Callback VI to then discard the original object and pass the newly created object to the user event? That is quite a bit of unneeded overhead.

 

Generally the best design would be to simply keep the .Net related functionality in the Callback VI and pass a LabVIEW data element to the user event instead of just routing through a copy of the original .Net event data.

Rolf Kalbermatter
My Blog
0 Kudos
Message 2 of 10
(2,073 Views)

That is unfortunately my problem, I never close the refnum on purpose. Closing the refnums means I would not receive the next set of data and thus no new event would be triggered. The VI gets stuck in the loop waiting for "new reference" that never appears. The front panel should ideally constantly update and show the new data for hours. The refnums only close after hitting the stop button end the loop ends. It would be great if I could dispose the held data after every event. Any suggestion?

 

The PulseReadyEventArgs SubVi was actually provided by the electronics people I bought the hardware from, so I did not really touch it and just call it in my main program. I'll have a look if I can improve it. 

0 Kudos
Message 3 of 10
(2,056 Views)

@ThomasTag wrote:

That is unfortunately my problem, I never close the refnum on purpose. Closing the refnums means I would not receive the next set of data and thus no new event would be triggered. The VI gets stuck in the loop waiting for "new reference" that never appears. The front panel should ideally constantly update and show the new data for hours. The refnums only close after hitting the stop button end the loop ends. It would be great if I could dispose the held data after every event. Any suggestion?

 

The PulseReadyEventArgs SubVi was actually provided by the electronics people I bought the hardware from, so I did not really touch it and just call it in my main program. I'll have a look if I can improve it. 


That doesn't add up! You do close the EventArg refnum in the callback VI. If what you describes would be the problem, it wouldn't work that way either. But instead you create a copy of the EventArg and pass that along to the user event and never ever close it. That of course consumes more and more memory.

 

In case if it isn't clear I'm talking about the red circled refnum. That definitely and absolutely certainly needs to be closed somehow.

 

BlockDiagramMemoryFail.png

 

The blue ones are in fact related and as such should indeed not be closed. But I would get rid of that altogehter and simply copy the array data into a LabVIEW array and pass this array from the callback VI to the user refnum.

 

Also even if you close the red refnum you still will leak memory. When you copy that Ampitudes refnum in the callback VI you crate an additinal reference to it. Even if you close the original refnum to the EventArg itself, this open refnum will keep that Amlitudes subdata alive in memory. When you then retrieve this refnum again in the user event it will create another reference to that data. Now you don't close it and there are two references to it that keep it in memory, once you do close it in the user event handler, there still is one unclosed reference (from the copy in the callback VI) that keeps this data valid.

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 10
(2,040 Views)

This makes me realise how little I understand Labview. I am pretty sure the solution to my issue lies somewhere in your answer. I closed both refnum in the event structure as per screenshot and of course as you mentioned the leak(s) persists. From what I understand you are pointing at the SubVI as the main issue. I admit that I am still unsure how to solve it. I deleted the copy of the EventArgs (Vi attached). With the copy gone I do not know how to implement the constructor node. Fun fact, although this subVI is not quite working and no data is displayed, there is still a leak when I run the main program. Memory usage increases slowly to additional 5 MB over 10 sec and then drops by 5 MB and so on.

 

You said "..get rid of that altogehter and simply copy the array data into a LabVIEW array and pass this array from the callback VI to the user refnum." Which parts exactly would you replace?

Download All
0 Kudos
Message 5 of 10
(2,001 Views)

That has little to do with LabVIEW and a lot with .Net. Just because Microsoft believes that .Net programming is so simple that everybody can do it, doesn't make it true. 😀

 

And .Net events have baffled many people, even somewhat experienced programmers. The indirect data flow through events needs some different thinking to get your head properly wrapped around it. It defies not only sequential programming, which is the standard in any text program language but also dataflow programming like in LabVIEW.

 

So while I can't write it out for you in detail since I do not have the .Net component you use, this is basically what I'm talking about:

 

 

 

 

Rolf Kalbermatter
My Blog
Download All
0 Kudos
Message 6 of 10
(1,987 Views)

@rolfk wrote:

That has little to do with LabVIEW and a lot with .Net. Just because Microsoft believes that .Net programming is so simple that everybody can do it, doesn't make it true. 😀

 

And .Net events have baffled many people, even somewhat experienced programmers. The indirect data flow through events needs some different thinking to get your head properly wrapped around it. It defies not only sequential programming, which is the standard in any text program language but also dataflow programming like in LabVIEW.

 

So while I can't write it out for you in detail since I do not have the .Net component you use, this is basically what I'm talking about:

 

 

 

 


I thought it was LabVIEW that was so simple that everybody could do it?  😄

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
0 Kudos
Message 7 of 10
(1,955 Views)

@billko wrote:


I thought it was LabVIEW that was so simple that everybody could do it?  😄


In case you haven't noticed, NI backed away from that sales pitch considerably. 😀

Rolf Kalbermatter
My Blog
0 Kudos
Message 8 of 10
(1,950 Views)

I spend some time looking through VIs you provided. The structures makes a lot of sense and the best is how simple they are compared to my attempted! Thanks for that. I implemented the code into my broader program and the memory leak disappeared.

 

There is only one smaller leak left which might not quite fit this topic but I’ll ask anyways. As soon as the signal arrives at the event, I read it into the array ‘amplitude’ (vi attached). No leak so far. I want to use the incoming data as a trigger For a parallel process that moves a linear stage. However, since filling an array does not create an event, I chose Value signalling to triggers the event that move my stages. This works, but the signalling causes the leak. So I tried to initialise the array and replace array subset but the leak persists. I cannot initialise the array outside the loop since the number of data points of signal varies. I guess signalling creates a copy every time it makes an event?

0 Kudos
Message 9 of 10
(1,913 Views)

Forgot to attach the VI..

0 Kudos
Message 10 of 10
(1,911 Views)