LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

.net reference management when we use “.net object to Variant.vi”.

Problem statement: Memory is being occupying when we use “.net object to Variant.vi”

Case 1: Without using “.net object to Variant.vi”.

Result : No memory leak

VijendrakumarYashodhara_0-1652416545616.png

 

Case 2: With using “.net object to Variant.vi”.

Result : Memory occupies.

VijendrakumarYashodhara_1-1652416545620.png

Please help regard. Thanks in advance.

 

0 Kudos
Message 1 of 12
(313 Views)

You use two separate terms in your message which may look like the same but are not. "Memory leak" and "Memory occupied" is not the same. Memory occupied is simply that LabVIEW allocated memory but hasn't deallocated it. LabVIEW has a lazy memory deallocation policy. That does not mean that it forgets the memory, but only that it doesn't immediately deallocate it whenever it is not needed anymore but instead puts it on a list of memory to eventually deallocate and when it needs new memory it will first look there if it can find memory before requesting new memory from the OS Heap Manager.

Memory leak is when the application forgets about a memory allocation and therefore never ever will reuse or deallocate that memory.

 

Variants could very well contain lots of data that LabVIEW needs to allocate and may not always be able to reuse as is immediately.

 

So how do you determine that that object is not deallocated? Just by looking at the memory slowly increasing? That is a bad method. You need to find a way to monitor the actual object count in your assembly.

 

And if you convert a .Net refnum to a variant it actually creates a new reference to that refnum. And that refnum is then stored in the front panel control and therefore another reference is created. Now you have three references to the same object open but only close two of them.

 

What happens if you remove the variant front panel control?

 

And ohhh, the seconds Reference Close is not needed. The refnum constant is only used for its type and does not reference any object. Accordingly there is no reference that could be closed or decremented. It won't hurt really as LabVIEW ignores Close requests on refnums that are the canonical NotARefnum value, but still.

Rolf Kalbermatter
Averna BV
Message 2 of 12
(285 Views)

If you posted the code we wouldn't need to recreate it.

 

Closing a constant is redundant.

 

This does seem to be leaking (e.g. memory usage grows, about 1 MBi / min):

DataSet dotNET.png

 

The memory is mostly released when the VI is stopped.

 

The problem is, DataSet isn't a type that LabVIEW can convert to a native LabVIEW type. So the variant is a DataSet .NET object.

wiebeCARYA_2-1652431161945.png

 

Note that there are 3 .NET objects! Only 2 are closed.

 

So, the object in the middle needs to be closed... Or, you can use it directly, and not use Variant To .NET Object.vi:

 

wiebeCARYA_3-1652431318445.png

 

Message 3 of 12
(272 Views)

@rolfk wrote:

And if you convert a .Net refnum to a variant it actually creates a new reference to that refnum. And that refnum is then stored in the front panel control and therefore another reference is created. Now you have three references to the same object open but only close two of them.

 

What happens if you remove the variant front panel control?.


It's not the front panel control.

 

It's .NET Object To Variant.vi.

 

If the type can't be (or isn't) converted to a native LabVIEW Object, a copy of the original object is created.

 

I'm not sure if Copy or Clone is used... AFAIU Clone would be a shallow copy, Copy a deep copy  

Message 4 of 12
(267 Views)

BTW, IIRC, this is especially tricky when working with datasets from databases.

 

Some 'database' SQL queries (Excel) can return different datatypes in a dataset.

 

Empty cells return void objects, not null references. So converting the data (usually system.string, etc) with .NET Object To Variant.vi will create a leak, but only if cells are empty.

 

This is easily overlooked.

Message 5 of 12
(260 Views)

wiebe@CARYA wrote:

I'm not sure if Copy or Clone is used... AFAIU Clone would be a shallow copy, Copy a deep copy  


It's almost certainly a Clone, it means LabVIEW creates a new refnum but only increases the refcount for the original object. But that object won't leave memory before the refcount reaches 0.

 

Strictly speaking you could claim that LabVIEW is somehow forgetting to deallocate the refnum inside the variant stored in the front panel indicator when it overwrites it with a new variant in every loop iteration. Proper memory refcount administration would require LabVIEW to deallocate/close all objects referenced by the variant. And it absolutely certainly does that for its own native data types such as arrays and strings. That it doesn't seem to do that for a .Net refnum looks more like an intentional omission than an accident. Most likely if they did that there would be some situations where the code actually can crash without LabVIEW being able to prevent it, as the .Net CLR tries to do something in the background after the object was already closed. It's still a bug that could be reported but the fix for this MAY be worse than the current issue and/or require a fundamental redesign of how LabVIEW deals with .Net (which may be something on the radar as they ponder about how to support .Net 5 and 6 and Core assemblies in an upcoming version, and no don't expect it to appear in LabVIEW 2022).

Rolf Kalbermatter
Averna BV
0 Kudos
Message 6 of 12
(250 Views)

I meant "Memory leak" and "Memory occupied" is same 🙂

What happens if you remove the variant front panel control?

If I remove variant front panel then also same case. But looks better.

0 Kudos
Message 7 of 12
(232 Views)

@rolfk wrote:

Strictly speaking you could claim that LabVIEW is somehow forgetting to deallocate the refnum inside the variant stored in the front panel indicator when it overwrites it with a new variant in every loop iteration. Proper memory refcount administration would require LabVIEW to deallocate/close all objects referenced by the variant. And it absolutely certainly does that for its own native data types such as arrays and strings. 


LabVIEW does do that for all native by value types, but not for any of the by reference types.

 

So it seems we should treat variants with references as reference type. They need to be closed manually, but will be closed automatically when the top level VI stops. 

 

I think the 'mistake' here is that .NET Object To Variant converts to a copy the object.

 

I would prefer an error if there's no native by value type, at least as an option.

 

It seems weird to me that when the user wants to get rid of a complex reference, (s)he gets the complex reference as a copy, wrapped in a variant. That's more complexity, not less.

 

With an error out it would be easy to manually 1) insert the object or 2) a copy of it in a variant or 3) leave the default variant. As it is, it's fairly hard to undo what .NET Object To Variant did.

Message 8 of 12
(218 Views)

Memory leak means if an application forgets about a memory pointer it allocated. Memory occupied simply is all the memory that an application has allocated. They are not the same. Typically an application has LOTS of memory occupied nowadays, but ideally zero memory leaks.

 

In LabVIEW it is extra complicated since your VI may allocate huge amounts of memory and in the sense of your VI it may seem like it is lost. But LabVIEW still knows that that memory is allocated and simply needs it because you have stored that huge data into a shift register or in a front panel control. LabVIEW has no way to guess if you do not intend to use data anymore, or if you actually even would very gladly have it to throw it away unless you explicitly clear that data by writing an empty data element to it.

 

Real Memory leaks can happen in LabVIEW, where it actually forgets about memory it allocated and leaves dangling buffers around, but they are extremely rare nowadays unless you venture into the realms if interfacing to external code, be it shared libraries or assemblies. Aside from real bugs in those libraries there is also the difficulty that LabVIEW simply has no way to verify that what you told it to send to the shared library is actually what that shared library really expects. If there is a mismatch between those two, VERY bad things can happen and quite often do!

Rolf Kalbermatter
Averna BV
Message 9 of 12
(216 Views)

@VijendrakumarYashodhara wrote:

I meant "Memory leak" and "Memory occupied" is same 🙂

What happens if you remove the variant front panel control?

If I remove variant front panel then also same case. But looks better.


Maybe use something like this:

 

.NET Object To Variant.png

 

Pick a case that suits you. Make sure to test a lot (I didn't).

 

There's overhead, you might try to avoid converting the DataSet to variant altogether. 

 

0 Kudos
Message 10 of 12
(209 Views)