LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Which references need to be "Closed"?



@BJK wrote:

I can't remember exactly, but I think I was using LabVIEW 6.1 (now I am using 7.0).
Maybe that was the problem!!


It IS the problem. LabVIEW before 7.0 always returned unique VI server references and therefore you had to close them explicitedly in order  to avoid memory leaks. A general thum of rule for >= 7.0 is probably that properties returning owned references will be really static and don't need to be closed (but doing so anyhow does absolutely not hurt). The Owner reference however is not an owned reference of the VI object you access the property of so it is a unique reference and needs to be closed explicitedly.

Rolf Kalbermatter
Rolf Kalbermatter
My Blog
Message 21 of 33
(3,665 Views)


@Dynamik wrote:
 
According to these rules, and in the case of my example, memory IS allocated by "Snd Play Wave File.vi", but only once - no matter how many times it's called.  That memory is de-allocated when the Top-level VI finishes executing.


I think that this statement is not entirely true. The "Snd Play Wave File.vi" will likely allocate a new Application reference everytime it is executed. As such it is most probably a bug but definitely an example of bad programming style.

Rolf Kalbermatter
Rolf Kalbermatter
My Blog
0 Kudos
Message 22 of 33
(3,675 Views)
Hi Rolf,
      After reading your post, I modified the VI to pass-out the un-closed reference (cast to U32) to see whether reference would be unique on each iteration.  The result is clear as mud! 0xFFFFFFFF is always returned... interesting, but not very helpful. Smiley Mad  


rolfk wrote

... The "Snd Play Wave File.vi" will likely allocate a new Application reference everytime it is executed.



Cheers
When they give imbeciles handicap-parking, I won't have so far to walk!
0 Kudos
Message 23 of 33
(3,633 Views)


@Dynamik wrote:
Hi Rolf,
      After reading your post, I modified the VI to pass-out the un-closed reference (cast to U32) to see whether reference would be unique on each iteration.  The result is clear as mud! 0xFFFFFFFF is always returned... interesting, but not very helpful. Smiley Mad


You are right I just did a small test and the local application reference seems to be always 0xFFFFFFFF in LabVIEW 7.1.
But just to check it out I tried the same in LabVIEW 6.1 and there it is the same. This is however obviously only the case for local application references and an optimization. Once you connect a machine name to the Open Application Refernce node, even if it is "localhost" which means LabVIEW is connecting to itself but over TCP/IP, the references are unique and need to be closed properly in order to avoid memory leaks. As such I think it is still a good idea to always close VI references and definitely explicitedly opened (Open .... function) ones.

Rolf Kalbermatter
Rolf Kalbermatter
My Blog
Message 24 of 33
(3,632 Views)
Hi Rolf,


rolfk wrote:

I think it is still a good idea to always close VI references and definitely explicitedly opened (Open .... function) ones.

Rolf Kalbermatter



I'm going to follow your advice about always closing references which I've explicitly "Open"ed.  I guess most of the uncertainty is related to references not explicitly opened.  Lately I've been working with databases (MS Access, SQL Server) and have come across yet another example (for which there's no help in LabVIEW)

The way it works is, one opens a Connection, then a Command, then specifies the command-text, then "Executes" the command.  Execute returns a RecordSet reference - which I think should be closed - whether it's used or not.

 


"Noah, how long can you tread water?"

Attachment exe.GIF (3 kb)

Message Edited by Dynamik on 01-21-2006 04:36 PM

When they give imbeciles handicap-parking, I won't have so far to walk!
Message 25 of 33
(3,629 Views)


@Dynamik wrote:

I'm going to follow your advice about always closing references which I've explicitly "Open"ed.  I guess most of the uncertainty is related to references not explicitly opened.  Lately I've been working with databases (MS Access, SQL Server) and have come across yet another example (for which there's no help in LabVIEW)

The way it works is, one opens a Connection, then a Command, then specifies the command-text, then "Executes" the command.  Execute returns a RecordSet reference - which I think should be closed - whether it's used or not.


This is ActiveX/COM and there is a strict rule. Always Release an object you receive from whatever after you do not need it anymore. Of course this may sound strange in terms of LabVIEW but COM objects maintain a refcount and deallocate themselves after that refcount reaches 0. Any method returning an object pointer is supposed to call that objects AddRef function which increments the refcount. LabVIEWs Close Reference function for ActiveX does mainly call the objects Release method, which decrements the refcount and then disposes of LabVIEW's internal refnum leaving the rest to the COM object itself.
Without calling the Close Reference function you not only loose memory for the LabVIEW refnum (a few bytes per refnum) but actually can introduce very nasty problems depending on the ActiveX control. The object returned by the COM method will stay in memory and consume memory too, sometimes considerable amounts of it and with some (not so nice) ActiveX controls it may prevent LabVIEW from closing properly since the library implementing the ActiveX control refuses to unload from memory as long as one of its objects is still not destroyed. The only way to quit LabVIEW then is to kill it through the Windows Task Manager which will forcefully purge any libraries that refuse to unload.

LabVIEWs own VI object hierarchy does things somewhat similar to ActiveX but is not built on COM/ActiveX at all as that would not allow to port it to non-Windows platforms. And in LabVIEW 6.x the whole functions even quite similar to COM in that it allocates new refnums (object references whenever an object is returned somewhere). However NI found that those references don't need to be allocated every single time again and since they have full control over the VI server object hierarchy they introduced an optimization in LabVIEW 7 where methods and properties do not return unique refnums anymore for owned subobjects. As long as the owning object is still active a subobject in the VI server hierarchy will always be present too and once the owning object is gone the subobject won't exist anymore either. This is not so much to allow LabVIEW programmers to be lazy about Closing VI references as much more about conserving resources as each unique refnum will consume memory and space in a resource container NI chose to call MagicCookieJar. The Close Reference function has been made smart enough to recognize the difference between unique refnums and static refnums and will consequently only act on unique refnums making a Close Reference node on a static refnum a NOP (No Operation).

Instead of trying to "optimize" a diagram by  trying to avoid Close Reference functions whenver possible and risking memory leaks either because you overlooked a certain refnum being dynamic or you upgrade to a newer LabVIEW version that happens to change the behaviour of a refnum from static to dynamic because NI had to fix a problem somewhere, it is much better to simply be consequent and always close any refnums properly once you are done with the object that this refnum refers to.

Rolf Kalbermatter

Message Edited by rolfk on 01-22-2006 12:48 PM

Rolf Kalbermatter
My Blog
Message 26 of 33
(3,605 Views)

Hi Rolf,

      5 Stars is insufficient payment for your last post, but that's all there are! 


Instead of trying to "optimize" a diagram by  trying to avoid Close Reference functions whenver possible and risking memory leaks either because you overlooked a certain refnum being dynamic or you upgrade to a newer LabVIEW version that happens to change the behaviour of a refnum from static to dynamic because NI had to fix a problem somewhere, it is much better to simply be consequent and always close any refnums properly once you are done with the object that this refnum refers to.


Just a small point: if the above quote refered only to ActiveX/COM, then this point was clearly made early in the thread - and more-so by your post.  However, if this advice applies to all references then I must emphasize:

my interest in effectively handling references isn't so much for "optimization" as it is for clarity.

Knowing it's not effective to close every reference in Control[]s references allows for a cleaner diagram. (Cleaner-> easier to maintain -> more reliable.)

Cheers!
When they give imbeciles handicap-parking, I won't have so far to walk!
0 Kudos
Message 27 of 33
(3,577 Views)

Hi Dynamik,

Not to completely beat this topic into the ground, but one of my style rules for people who wrote VIs for me a while back was to always close references, no matter what kind they were (see my previous post toward the beginning of the thread where I advocate this rule).  It may take more space on the diagram to close references, but it gave me peace of mind knowing that all references were being closed...I would argue that the programs were more maintainable because we never had to go back over all the places in our code where references were being opened to see if closing them solved any problem we might have been encountering...this is because the references were always being closed regardless of what type they were.

-D

Message 28 of 33
(3,566 Views)


@Dynamik wrote:

Just a small point: if the above quote refered only to ActiveX/COM, then this point was clearly made early in the thread - and more-so by your post.  However, if this advice applies to all references then I must emphasize:

my interest in effectively handling references isn't so much for "optimization" as it is for clarity.

Knowing it's not effective to close every reference in Control[]s references allows for a cleaner diagram. (Cleaner-> easier to maintain -> more reliable.)

Cheers!


Well,for ActiveX you MUST close all references and for VI server I recommend VERY STRONGLY to close all references independant how you got them. Performance wise a Close Reference on a static reference is a NOP and therefore optimized away by the LabVIEW compiler.

Diagram wise I represent the (minority?) of people that think that properly closing any reference whatsover is creating a much clearer diagram than having to second guess why some references are closed and why others not. Remains the fact that a reference you do not need to close in LabVIEW 8.0 my suddenly require to be closed in LabVIEW 8.1 for various architectural changes in LabVIEW or some oversight by NI. While they would mention something like that in the upgrade notes it is very likely that I wouldn't remember at the time I convert an old program to this new version, nor that that program made use of "optimized" references. But that might be my old age! Smiley Very HappySmiley Wink

Don't forget the time you need to verify that you can safely ignore the Close Reference. That is IMO spent much better in other areas.

Rolf Kalbermatter

Message Edited by rolfk on 01-23-2006 07:53 AM

Rolf Kalbermatter
My Blog
Message 29 of 33
(3,563 Views)
Hi Darren,
      You're right, of course.  Lacking a way to know whether it's effective to close them [VI Server references] closing is the best policy.
..though, I suspect that even you will make exceptions - as in the case of Controls[](?)
The whole thread probably seems arcane to most, but I'm really "anal" about my code, and wanted to understand these "things" better.
Thanks again to you and all who've taken the time to share their knowledge and perspectives! Smiley Happy
Cheers!

Message Edited by Dynamik on 01-23-2006 12:43 AM

When they give imbeciles handicap-parking, I won't have so far to walk!
0 Kudos
Message 30 of 33
(3,561 Views)