03-22-2015 05:35 PM
LV 2013, Win7
I have a program where a menu item can open or close a particular window.
That window is large, contains 72 SubPanels, each SubPanel contains a single instance of a reentrant VI (called the BLOCK VI).
I have a LARGE memory leak (about 100 MBytes ) each time the window opens and closes. I'm using the Windows function WORKING SET SIZE to judge memory usage.
In chasing this, I have put a DIAGRAM DISABLE around the entite block diagram of the BLOCK VI. That means it cannot allocate anything in code.
The problem still exists.
I seem to have found the problem, but I don't understand why - it seems to contradict the HELP.
The HELP text for INSERT VI into a SubPanel says this:
I interpret that highlighted part as meaning when my Window VI stops, the VIs will be REMOVED automatically (They have been stopped before).
But that doesn't seem to be the case.
Here is the Memory usage before I discovered the removal angle. I Open and close the window 4 times:
If I REMOVE the VI myself, then here's what it looks like:
--- That's more like I would expect - whatever it uses when open, it gives back when closed.
I have verified it's a real problem - I have a stress test to cycle the open/close operation, and it eventually dies with a MEMORY FULL message.
So, here's the code:
There is a tab control with 12 pages on it. Each page has nothing but six SubPanels on it.
So, I collect those 72 SubPanel references.
For performance reasons, I pick out the page that is showing (set from the last time the user closed it), and launch the blocks for that page first.
I then bring up the window's front panel, and then launch the blocks that are not showing, so that they are ready to go if the user switches tabs.
Here is the LAUNCH BLOCKS code:
I convert the generic ref to a SubPanel Ref, open a CALL and COLLECT reference to the BLOCK VI, and insert the VI, then RUN the BLOCK VI instance.
No errors occur here.
When I CLOSE the window, here's what happens:
The instances of the BLOCK VI have already been told to quit (for this test, they are entirely disabled anyway, so do not run).
I WAIT ON ASYNCH CALL for each one (I don't really need to collect anything, but I need to wait on them quitting. I've been going back and forth between C&C and other methods of doing that.
It's that REMOVE VI part that I DISABLED and ENABLED to produce the mem usage graphs above. Originally I didn't have it, but I tried and it seems to solve the problem.
But why? The help says that I don't need it. After this code, the window VI quits, so they should be removed automatically.
But yet the memory piles up...
QUESTIONS:
1.. Why do I have to REMOVE the VI?
2... Does it matter if I RUN the VI before INSERTING, or INSERT before RUNNING?
Blog for (mostly LabVIEW) programmers: Tips And Tricks
03-22-2015 07:07 PM
03-22-2015 09:09 PM
@CoastalMaineBird wrote:
I interpret that highlighted part as meaning when my Window VI stops, the VIs will be REMOVED automatically (They have been stopped before).
But that doesn't seem to be the case.
I'd interpret it the same way you would.
But, we should be fair. "Automoatically" and "immediately" aren't interchangable. We are also making the assumption that if one thing is true, the opposite is also true. It guarantees how long it will stay in memory, but it never claims when it will leave.
What is the manual removal you're discussing?
03-23-2015 03:12 AM
@CoastalMaineBird wrote:
The HELP text for INSERT VI into a SubPanel says this:
QUESTIONS:
1.. Why do I have to REMOVE the VI?
2... Does it matter if I RUN the VI before INSERTING, or INSERT before RUNNING?
I would say that the help is poorly phrased. It's quite easy to demonstrate that the when a VI stops running, the VIs in its subpanels are not removed automatically (see the example). I'm assuming that what was meant here is "until the VI that contains the SP goes idle or out of scope", which is not how most people would interpet "stop". As long as the VI stays in run mode, even if it's not actually running, the FP stays in the SP unless you remove it.
This is the behavior you're seeing and it explains the memory issues. Since you're not removing the FPs, they are apparently staying open, thus making your close ref a no-op, and since you then keep going, they're apparently staying open in the background. This is a guess. I haven't checked it, but it seems to match what you're describing.
And no, I don't think the order of the operations matters, but I would suggest running the VI before inserting, to avoid a case where you have a non-running VI visible.
03-23-2015 03:17 AM
@CoastalMaineBird wrote:
I interpret that highlighted part as meaning when my Window VI stops, the VIs will be REMOVED automatically (They have been stopped before).
When the owning VI, the one with the subpanel, stops the VI will be removed.
Have you saved the subpaneled VI with some big default data?
/Y
03-23-2015 06:47 AM
It guarantees how long it will stay in memory, but it never claims when it will leave.
Well, OK. A lawyer might read it that way. But in fact, the thing NEVER leaves, as evidenced by the memory leak. Eventually (8-10 open/close cycles) and memory fills up.
What is the manual removal you're discussing?
I meant explicitly calling the REMOVE VI function of the SubPanel.
Blog for (mostly LabVIEW) programmers: Tips And Tricks
03-23-2015 06:52 AM
As long as the VI stays in run mode, even if it's not actually running, the FP stays in the SP unless you remove it.
I've never been real clear on the difference between "being in run mode" and "running".
Is "being in run mode" the same as "reserved for running"?
Hmmm. I do have a static reference to the containing window. Perhaps that is enough to keep it in "run mode" (reserved) and keep the things loaded.
I don't think the order of the operations matters, but I would suggest running the VI before inserting, to avoid a case where you have a non-running VI visible.
Well, that's a good thought, but I'm already taking care of that by inserting the VI, running them, and THEN showing the front panel.
Blog for (mostly LabVIEW) programmers: Tips And Tricks
03-23-2015 06:58 AM
When the owning VI, the one with the subpanel, stops the VI will be removed.
Well, that doesn't seem to be happening. I think TST is right, the word "stop" should be replaced by "goes out of scope" or whatever the term is for no-longer-reserved-for-running.
Have you saved the subpaneled VI with some big default data?
No. No default data at all. There's an empty chart, an empty 3-D graph, an empty Intensity graph, 51 channel selectors (that I keep with only one channel in the menu), 51 numeric indicators, and a few assorted oddments. But each instance is initialized independently, so there is no value in any defaults.
Blog for (mostly LabVIEW) programmers: Tips And Tricks
03-23-2015 07:03 AM
NEW INFO:
If I use option 0x80 (CALL and FORGET) instead of option 0x100 (CALL and COLLECT) to launch the blocks, and close the reference immediately after running it, then the leak returns EVEN IF I REMOVE VI from SubPanel when closing.
Given that I have disabled the ENTIRE block diagram of the BLOCK VI, the VI quits immediately after launching anyway. But COLLECTING seems to make a difference.
Blog for (mostly LabVIEW) programmers: Tips And Tricks
03-23-2015 07:21 AM
NEW INFO:
I removed the static references to the WINDOW VI (I substituted a VI TYPE constant, and a PATH constant).
No change in behavior.
Not sure if it matters, but the WINDOW VI is itself called with a CALL AND FORGET procedure. The ref is closed immediately after RUNNING, as the examples suggest.
Maybe that confuses the REMOVE process ?
Blog for (mostly LabVIEW) programmers: Tips And Tricks