LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Why does this extra REG EVENTS cause memory leak?

LabVIEW 8.6.1f1, Win XP/Vista

 

My client reported a memory leak in a particular section of my code - my own tests confirmed it.

 

Although I have found it and eliminated it, I still don't understand what's really happening.

 

The RTEC RECEIVER CONTROLLER vi produces a cluster with various (maybe 30) event refnums in it.

 

For this particular piece of code, I am only interested in 5 of those events.

 

I was experimenting with registering the cluster as a whole (it works), and I inadvertently left the 2nd REGISTER EVENTS function in place.

 

So there are TWO event registration refnums, but only one of them is being used.

 

As the program proceeds, more and more memory is being consumed by LabVIEW (as reported by Windows Resource Monitor).  Leaving the program with this particular window running overnight would use up a gig or RAM.

 

I verified that nothing else was consuming it - disabling the actual data handling did not fix the problem - eliminating this extra registration did fix it.

 

So my question is - why?

The registration only happens once, and then there are a million events or more in a 12-hour period.

 

I can guess that the registration creates some sort of queue within LabVIEW for the events to reside in.  With no EVENT structure tied to that refnum to consume the events, that queue expands forever.

 

Is that a reasonable guess, or is there something I am missing?

 

 

 

 

18633iF0CA7B8066B66908

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 1 of 18
(3,783 Views)

 


@CoastalMaineBird wrote:

 

I can guess that the registration creates some sort of queue within LabVIEW for the events to reside in.  With no EVENT structure tied to that refnum to consume the events, that queue expands forever.

 

Is that a reasonable guess, or is there something I am missing?


 

Yes, it's a very reasonable guess and is most likely what's happening.

 

You might say "LabVIEW could see I'm not actually doing anything with the reference and could therefore optimize the code by ignoring it (which is something LV does in some other cases)", but I'm assuming this is a corner case whoever wrote the original code did not think about, because this could be implemented only in a case where the node neither outputs a reference nor gets one as an input.


___________________
Try to take over the world!
0 Kudos
Message 2 of 18
(3,769 Views)

I have confirmed this.

If you register for an event, and do not wire that registered event wire to an event structure, the data from every time that event is generated gets left in the aether.

 

I attempted a flush event queue on the wire and I get an output equal to the number of events that have been generated.

However, this doesn't clear the event structure.

Generating the event again and clearing, yields +1 element in the queue. It doesn't reduce memory usage of LabVIEW.exe.

 

I ran into this issue when registering for an event inside of an init method of an object. I used the object in a VI but didn't use the event registration.

 

0 Kudos
Message 3 of 18
(3,614 Views)

What version LabVIEW ?

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 4 of 18
(3,606 Views)

I was using LV 2014.

0 Kudos
Message 5 of 18
(3,590 Views)

In general, each registration should not go to more than one event structure (and, apparently, as you can see, also not to less than one), because otherwise the behavior is undefined and you will get weird behavior. Considering that, you might wish not to do the registration at that point in time, but instead keep the event reference and register for the event when your consumer is actually ready. This should also allow multiple consumer to register.

 

FWIW, LV does (or at least did) have something along these lines where if you register for an event and wire the registration to an event structure and don't create a case for that event, the registered events will disappear and won't take up RAM.


___________________
Try to take over the world!
0 Kudos
Message 6 of 18
(3,537 Views)

So this re-raises the question I was originally investigating.

 

At the time, I was wondering about speed.  It's akin to having 30 telephones on my desk, but I'm supposed to answer only five of them.

If I register for all of them (the cluster), then they all ring.  Each ring, I have to determine if this is one of MY phones or not.

Whereas, if I register for only the ones I want, that is not an issue.  Any phone ring is for me.

 

But it's simpler wiring if I plug in the whole cluster. 

 

Tech Support said there should be no speed penalty, but now I wonder if I am leaking by doing that?

 

 

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 7 of 18
(3,487 Views)

My understanding is that if you wire the registration refnum to a structure, then the events will be cleared from the queue if you don't have a case to handle them. Before 2013, such events would reset the timeout counter for the timeout event. In LV 2013, this was apparently changed so that this doesn't happen. This is all not from personal experience, since I haven't done this myself.


___________________
Try to take over the world!
0 Kudos
Message 8 of 18
(3,472 Views)

Jack Dunaway had a very good presentation at NI Week a while back that demonstrated when memory leaks will occur with the event structure and what to avoid.

 

https://github.com/wirebirdlabs/LabVIEW-User-Events-Tips-Tricks-and-Sundry

 

The examples are what I found most interesting about the presentation.  He did mention this case of registering but not using the ref.

0 Kudos
Message 9 of 18
(3,431 Views)

@CoastalMaineBird wrote:

that queue expands forever.


Yes; this is one deficiency in the Events API were we need more control. But for clarification, the original behavior of a leak generated by unhandled events is correct and expected.

 

Though, there could be an argument that since no other wires were connected to `Register for Events()`, the compiler could have eliminated this in a dead code elimination transformation (Though, I would tend to argue against this, because the `Register for Events()` node is not purely functional and produces side effects which cannot necessarily be understood by the compiler. "Leaks" are sometimes created by design in order to make guarantees about allocation lifetime.)

 

But if it were wired, I would definitely say that it remains expected behavior.

0 Kudos
Message 10 of 18
(3,420 Views)