LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LabVIEW 8 does not close ref's the same as LabVIEW 7!?!

Hello!

I have been struggling with a difference between LabVIEW 7 and 8 in how the Close Reference functions for Active X objects. In order to fully understand the problem, let me first explain the process of how I got here.

I have an application in beta testing and we noticed a huge memory leak in LabVIEW 8, 8.2. I took a snippet of the code and worked on it a while to reduce the memory leak. I was closing every reference and could not explain it so I wrote the same code in VB and saw no memory leaks. I implemented the same code in LabVIEW 8 and still saw a memory leak. The code opens a graph control from a third party vendor and draws it. Each time the graph is drawn in LabVIEW 8, it costs about 30-40k. We have 8 graphs in our application bringing each iteration to 240-320k. The users are going to be reviewing between 96-384 samples in one sitting but we have no control over when the program quits. 384 samples reviewed in the graphs is 92,160k as a minimum. I was frustrated and about to send it to the thrid party vendor, AB Sciex, but they only had LabVIEW 7.1. So I converted it back to 8.0 and then to 7.1.1. I ran the code in 7.1.1 and there were little to no memory leaks! I even tried it in LabVIEW 7.0 and it worked the same as 7.1.1.

I monitored the memory of LabVIEW through the task monitor in Windows XP. I have tried it on a few XP machines and a 2000 machine and same answer on all. I also built a Task Monitor tool using .NET to graph the memory of the LabVIEW process. I verified that running the .NET example as an exe and the windows based task monitor behave the same and produce the same result.

So, I have an example that works in VB, LabVIEW 7.0 and 7.1.1. but 8.0 and 8.2 cause memory leaks! I have tried numerous things to force the removal of the references but nothing seems to have worked. Here is a list of things I have tried in LabVIEW 8 to force the closing of the reference:
- Error detection after each property node/invoke node to catch any errors for the mem leaks
- Deallocate Memory function is placed in every VI.
- All VIs running in the User interface thread to avoid thread collision, also tried running in the IO thread.
- Debugging turned off on all VIs.
- All references converted to controls (instead of constants) and made not visible on the front panel. I hoped this would not force an update to the FP or memory.
- All Open and Close references are in seperate SubVIs for memory deallocation.
- Time delay of 3 seconds in between each property node/invoke node to make sure deallocation can occur.
- Forced recompile and saved all. Rebooted in between all attempts and changes above.
- Put all code and ocx control in a SubVI and called it through the main program as a SubPanel. I can see memory deallocation, but its not a full deallocation. It deallocates about 40k, but the load eats up 80-90k. VB and LV7 deallocate about 20k, increase 55k for the load, then drops 30k after the load and results in about 3-4k in memory for LabVIEW.

I am hoping through this post that someone can help me out with understanding why LabVIEW 8 would handle closing references differently than that of LabVIEW 7. I feel as though i have attempted nearly everything I can to get LabVIEW 8 to work with this example. I have an open reference (ha thats funny) with NI to look at this but wanted to see if any of you had any thoughts? Thanks!

Try it out for yourself here please....
LabVIEW 7.1 Code (1.1Mb)
LabVIEW 8.2 Code (1.1Mb)
Third Party program(77MB)
Memory graphs between 7 and 8 (50k)
Memory Monitor Tool 8.2exe (700k)

Kevin Shirey | CLA | Champion | Senior Project Engineer II | DMC
0 Kudos
Message 1 of 3
(3,051 Views)

I didn't run the code, and I don't think there should be a difference between 7 and 8 (meaning this might be a bug), but I can give you some advice.

First, the Request Deallocation won't help. ActiveX reference refer to external resources, so LV will not dispose of them automatically until the VI goes idle.

Second, if you look inside the "open wiff" VI, you will see that you do have a memory leak. You're wiring a reference in, getting another reference inside and wiring that one out, without closing the original reference. I don't know if this is enough for your leak, but you might have this elsewhere as well.

Third, you might want to see if you can monitor the memory usage of specific VIs using the profiling tools. I don't know if this applies to ActiveX references as well, but it might help.

Fourth, if you have an error when dequeuing, your program will get stuck. This has nothing to do with the memory leak and will probably not happen, but I just thought I should mention it.

BTW, I like the error handling VIs. I haven't had the time to run them, but if I understand correctly what they do, it sounds interesting.


___________________
Try to take over the world!
0 Kudos
Message 2 of 3
(3,038 Views)
Thanks for the reply,

On the first issue, I believe this made sense as it made no difference, but was a recomendation from NI so I tried it.

On the second issue, I just put in a close ref on the input to the Variant to Data function. This ensures that the reference being passed iin will be empty. The Variant to Data function only creates a new instance of the type of reference being passed in. At this point in the code, the reference has already been closed  from a previous VI and I am only using it as a type, as I know it doesn't replace the reference. This was a good check though and looked at all my other variant to data functions just in case but still the same results in LV82.

Third thing is that I tried the profiling tools but it didn't offer a way to track active x data or the memory leak at all. They offered me how much average memory and max they used.

thanks on the fourth. I put in some extra error dialogs now there in case something does happen.

As far as the error detection VIs, they work very well for what I need them for. I like to put in unique error tags in each VI. So long as the error check VIs are in place after each routine, I know exactly where the error occurs because of the error code. So when an error occurs, a dialog box comes up with the LabVIEW error code, VI path and unique error code. It also provides an option to debug which is very cool. It will open the vi with the error and pause it. Then open the block diagram and turn on the light bulb and wait for you to unpause it. This lets you see exactly where the error happened so you can come back to it. It also can record it to a log file or ignore all errors of this type. There is still some things I need to do to it, but its been a work in progress over the years.

What boggles my mind is that the code has no memory leak in LabVIEW 7, 7.1 but has a loss of 40-50k each iteration i LabVIEW 8,8.2. If you have any other suggestions, I am certainly open to trying them.

I am currently investigating a subpanel option to encapsulate all the active x code in another VI and calling it dynamically. Its too early to tell how much this will change things, but I believe the memory leak is because the ocx control of the graph on the main panel is not being released because the main VI never goes idle. If this is true, then the ocx control will be forced to close and deallocate memory because of the dynamic call. When I have the results, I will post em.
Thanks!!

Kevin Shirey | CLA | Champion | Senior Project Engineer II | DMC
0 Kudos
Message 3 of 3
(3,033 Views)