From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Memory profiling in AF

Hello,

I have a large application written in AF, and my memory keeps growing while I use the program. I have some questions about memory usage in AF:

(1) What is the proper way to terminate an actor, and free the memory it used? I am using the 'send normal stop' command after I am finished with my actor, but the system seems to keep it in memory. Could be doing something wrong here to terminate the actor?

(2) Labview's Tools > Performance and memory profiles really doesn't show me anything. Everything shows zeros. Is that normal?

(3) Is there a way to view how many active actors I have running, so I can determine if something is not being closed properly?

Any insight is appreciated! Sorry if this has already been covered somewhere.

0 Kudos
Message 1 of 11
(6,743 Views)

In reverse order:

(3) The debugging tools for actors are as (in)complete as for any application built using reentrant VIs. As such, no, there is no way built into LabVIEW to see how many actors are running. It is something I and others in the AF community have asked for. BUT... if you use the Desktop Execution Trace Toolkit, you can see the start and stop of the clone VIs. Also, there is a Boolean input to Launch Actor.vi to open the front panel of actor core... then you'll be able to see the panels of your running actors and abort them if needed. The Boolean only works in the development environment, not in the run time environment. It's meant for debugging... if you want to open panels in the run time engine, change the VI Properties of your Actor Core.vi or add an Invoke Node for "Front Panel.Open" method.

(2) Check the "# Runs" column. You should see numbers there. On Windows, it is not uncommon for VIs to be permanently at zero ms because they run faster than the timer resolution on the desktop (I think that's like 16 ms). The AF has lots of VIs that are asleep most of the time and wake up only to flicker to life and then sleep again. It's part of why the system scales as well as it does. Again, the Desktop Execution Trace Toolkit gives you a much better view of the performance of an AF application.

(1) Sending the Stop Message (normal or emergency) is the right way to stop an actor. It is your actor's job in its Stop Core.vi to clean up any resources that it acquired during the run. Most resources will auto cleanup, but if your actor launched any nested actors, those nested actors are independent and will keep running even if their caller quits (that's by design) so your Stop Core.vi needs to pass along the stop message, if that's correct behavior for your application.

0 Kudos
Message 2 of 11
(4,065 Views)

Just one note on memory:

I believe all LabVIEW classes stay in memory for the lifetime of the application. There is no unloading of the class itself. (I think the reason is that it's "too difficult to keep track of all possible references to class members" or something like that... AQ can correct me here!)

This is interesting if you are dynamically loading classes, e.g. a bunch of "measurement" classes in a test sequence. Even though you may only need the classes sequentially, your base memory footprint will only ever increase until all possible classes are loaded.

FWIW I'd love a way to "force unload" a class, although there would likely be significant caveats...

0 Kudos
Message 3 of 11
(4,065 Views)

fabric wrote:

Just one note on memory:

I believe all LabVIEW classes stay in memory for the lifetime of the application. There is no unloading of the class itself. (I think the reason is that it's "too difficult to keep track of all possible references to class members" or something like that... AQ can correct me here!)

The bookkeeping is possible, but the performance cost for *every* data copy is extrordinary, and there is no method for cleaning out all the data instances, so the times when you could use it would be essentially none. I have found zero programming languages that support dynamic unload of types. Once a type is defined in a running system, it's defined forever unless you unload the application that is using it.

0 Kudos
Message 4 of 11
(4,065 Views)

The class private data is one thing, but when all the class methods plus all ancestor methods, plus all their dependencies are also stuck in memory... it can quickly add up. Even a way to force an edit-time unload would be most useful, but that's probably a topic for the Idea Exchange.

0 Kudos
Message 5 of 11
(4,065 Views)

There are conditions under which all the methods will leave memory. I've already coded as many of those in as I can think of. Unfortunately, those conditions trigger very very rarely. ("No VI outside of the class member VIs themselves in memory is using any of the parent class methods." ... occurs when the whole framework is dynamically loaded/unloaded, not just one plug-in of that framework.)

To trigger a true edit-time unload, we would need to add a menu item "Reset all controls, indicators, constants, global VIs, uninitialized shift registers and anything else I've forgotten in all VIs to default value". You can throw it up on the Idea Exchange, but I doubt it gets enough traction to justify the development costs. Generally, if you truly have a class that is unused in your project and is just lingering because of a dynamic load, and you really need to make it go away for some reason, closing the project and re-opening it suffices as a workaround. I know it is not desirable for some folks -- there are projects that can take a while to come back -- but you're into such a corner use case, I doubt this ever becomes a priority.

0 Kudos
Message 6 of 11
(4,065 Views)

AristosQueue wrote:

To trigger a true edit-time unload, we would need to add a menu item "Reset all controls, indicators, constants, global VIs, uninitialized shift registers and anything else I've forgotten in all VIs to default value".

Could you just hard-wire "True" to that value whenever I hit the "Run" button? It'd sure make debugging easier in a lot of situations.

0 Kudos
Message 7 of 11
(4,065 Views)

David Staab wrote:

Could you just hard-wire "True" to that value whenever I hit the "Run" button? It'd sure make debugging easier in a lot of situations.

All the situations except the ones where you're trying to debug a VI with particular inputs. 😉

How to change/improve LabVIEW's mix of "this is edit time" and "this is run time" and "this is debug time" is a major topic of conversation among lots of people. It is an environment that works generally well by eliminating the wall between editing and running, but there are fuzzy edges where it is hard to get to the side you want to be on. Based on the buzz, I'd guess you'll see some change to this sort of thing sometime in the next three to five years. That's a guess, but there's a lot of business interests pushing hard to get some improvement soon.

0 Kudos
Message 8 of 11
(4,065 Views)

AristosQueue wrote:

sometime in the next three to five years

......

0 Kudos
Message 9 of 11
(4,065 Views)

Here is the problem I am having with AF. I would like to continually kill and Launch many of the same actor, and on each launch I pass new data into the actor. Each time the actor is launched, it is placed into a subpanel for interaction. The problem I have is that when I kill the actor, and remove it from the subpanel,  then spawn a new one, my memory footprint grows (does not stay constant)! Each time I do this the memory grows. Is there anyway around this? This is why I asked of the proper way to stop an actor. I am overriding the stop core, and killing any sub actors that this actor may have spawned, but memory keeps growing.

Also the reason I don't want to keep the actors running, and pass new data into the running actor is because the subpanel is dynamic, and the number of actors needed is arbitrary depending on what data comes in. So ideally I would like to populate, un-populate, and re-populate my subpanel depending on what the data is doing (but this does not seem possible due to memory growing on each iteration of this process). Any insight is appreciated.

0 Kudos
Message 10 of 11
(4,065 Views)