LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

When are DVRs automatically deleted?

Solved!
Go to solution

Hi Folks,

 

I am experiencing a strange behavior with data value references in LV OOP:

 

I would like to equip a class with a data value reference. When the first instance of this class ist created, I create a new data value reference and a semaphore and put it in the private data cluster of the class.

 

Like this, after I create a new branch the data in both instances should be the same (i.e the dvr adresses the same part of the memory) and to avoid data access problems, the semaphore is used, to ensure, that the instances do not interfere, when they access the data. 

 

After a while the access vi throws error number 1 on the semaphore and error number 1556 on the reference. It seems that both, the reference and the semaphore are freed.

 

Ist there some garbage collector, that destroys references automatically after the constructor vi has finished, although there still exists a class which stores the reference?

 

Thanks in advance

 

Edit: If I read the data value references immediatly after I have called the class constructor and if I put a probe on the semaphore, I get the "invalid reference" as value, although the memory address has not changed. Strange!

0 Kudos
Message 1 of 19
(7,494 Views)
Solution
Accepted by topic author mthimm1

mthimm1 wrote:

 

Ist there some garbage collector, that destroys references automatically after the constructor vi has finished, although there still exists a class which stores the reference?


Yes there is! All LabVIEW refnums are garbage collected as soon as the tope level VI in whose hierarchy the refnum was created goes idle. So if you have an initialize VI that is started as top level VI and which creates your DVR and semaphore and that initialize VI is started dynamically (which actors are as far as I know) and then it ends its merry task and goes idle, the refnum is destroyed and your other actors won't see a valid refnum object anymore.

 

So it is important to create those refnums inside the hierarchy that is going to use them or alternatively have a top level VI that stays active for the duration of the entire program executation and delegate the creation of those refnums to that VI or some subVI which runs in that hierarchy.

Rolf Kalbermatter
My Blog
Message 2 of 19
(7,448 Views)
Solution
Accepted by topic author mthimm1

mthimm1 wrote:  and to avoid data access problems, the semaphore is used, to ensure, that the instances do not interfere, when they access the data. 

There is no need for the Semaphore.  The In Place Element Structure, which you use to access the DVR data, acts as a block (only 1 process can access it at a time).

 

References are destroyed when the creator of the reference is released from memory.  Maybe you should have your top level VI create the reference.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 3 of 19
(7,440 Views)

Thanks a lot!

 

This was a really weird problem for me, because the reference seemed to disappear at random times, which was really difficult to locate.

 

Do you know if there any way to turn garbage collecting off? Like this the adult programmer can decide himself, when which reference should be deallocated. This would be nice for dynamic creation and deletion of  data references in concurrent threads...

 

I have to admitt that I am new to LV but the way the problem of garbage collecting is solved here seems to me some kind of an anti pattern because there is also an explicit destructor for data value references.

 

Thanks also for your hint regarding semaphores. I am sure that this will save me some convas time in the future!

 

I will continue to use them in this case anyway, because I want to extend the blocking time to perform some other operations.

0 Kudos
Message 4 of 19
(7,391 Views)

Nope, garbage collection for refnums is not generally possible to disable, except for VISA refnums where you have an option in the LabVIEW Option dialogs to not automatically garbage collect them.

Rolf Kalbermatter
My Blog
Message 5 of 19
(7,379 Views)

@mthimm1 wrote:

I have to admitt that I am new to LV but the way the problem of garbage collecting is solved here seems to me some kind of an anti pattern because there is also an explicit destructor for data value references.

Not so much an anti-pattern as a reasonable rule which fails under specific circumstances. AFAIK, this behavior comes from long before automatic memory management and parallel processes were common, but because LV does do automatic memory management, NI did have to decide on when to clear up resources automatically. They chose a fairly reasonable rule of "clean up whenever the creator goes idle". "Adult programmers" aren't really relevant here, as LV does set things up automatically, so it shouldn't be surprising that it also cleans up automatically. If the adult programmer wants the responsibility of handling memory, they can use C. A more encompassing rule for LV would be "clean up automatically only when all your users are idle", but that would require more tracking.

 

The bottom line, as already suggested, is that in this case the adult programmer needs to understand how LV loads and unloads VIs and create the references in a hierarchy which will stay in memory.


___________________
Try to take over the world!
Message 6 of 19
(7,349 Views)

I am not against memory managment.

 

And, since I am new to LabView I did not want to critizise NI or the decisions they have made in order to provide a memory managment at all.

 

But this memory managment seems strange to me, since it limits the use with no reason. There are a lot well known and easy to implement strategies which provide a conservative garbage collection and do not destroy objects still in use. The aquisition of data refs is something I would like to delegate to the constructor of a class. Due to this reasons, it is difficult to understand for me, why the DVRs die with the Vi that created them.

 

As a first approach I am now planning to implement the following workaround:

 

Two VIs, one which is started asynchronously and creates the desired data reference and runs an while loop which stops if the reference has been destroyed externally. The other VI creates a queue wich transports a data reference. The queue is parameter for the first VI which sends the created DVR to the calling vi. Since the creating VI does not die, my reference lives until it is destroyed by the class destructor.

 

Do you think this is a resonable way to deal with my issue or is there something more simple?

0 Kudos
Message 7 of 19
(7,316 Views)

@mthimm1 wrote:
... it is difficult to understand for me, why the DVRs die with the Vi that created them.

Not the VI. The hierarchy (which is defined by a top level VI). That's an important distinction, because it means references do generally stay alive correctly. Like I said, there are other alternatives, but this is the mechanism LV has had for a very long time, and in most cases, it works fine. Where it breaks down is in the case where you run VIs dynamically (making them top level VIs) and obtain references there and those VIs stop before other VIs which use those references.

 

The easiest solution is generally to create the reference in a hierarchy which will stay around as long as that reference is used and usually there is no need to run a special VI just for that. In your case, it's unclear from your description whether the DVR belongs to an instance or to the class (like static variables in C++), but I assume you want it per instance. Often, the more readable option is not to put the DVR in the object, but to make a DVR of the object itself and use that to identify different instances of the class. This is a useful way of making by-ref objects in LV. In either case, you would want the code where the DVR is created to be in a hierarchy which keeps running (most likely the main VI).


___________________
Try to take over the world!
Message 8 of 19
(7,283 Views)

To add to what tst wrote, remember that objects(classes) in LabVIEW are by value, not by reference like in c++.

0 Kudos
Message 9 of 19
(7,276 Views)

LabVIEW doesn't have a "garbage collector" and I don't believe it is possible to add one easily like one can in an "everything has a reference" lanuage.  Garbage collectors, I believe, increment over all object references and find objects not refered to by any other still-live object.  That doesn't work in LabVIEW.  The "die with your creating hierarchy" thing works well in the large majority of programs that don't asynchronously call VI's.

 

Why are you using a DVR, by the way?   There are other ways in labVIEW to hold common data, such as an "Action Engine".

0 Kudos
Message 10 of 19
(7,261 Views)