02-11-2025 09:37 PM
I am encountering a memory growth issue while running my LabVIEW program. As the program executes, the memory usage (as monitored by task manager) keeps increasing until the program eventually crashes.
I have attached an image showing the main parts of my program.
If anyone has insights or suggestions on how to efficiently manage memory, I would greatly appreciate your advice.
02-11-2025 10:19 PM
Can you please tell us about your environment and your experience? You've been a member of the Forum for eight years, but you have only two posts, both this month.
Looking at your code, I see everything in Sequence fences. Is this FPGA code? If you've been reading this Forum for eight years, you'll know that "pictures" are not an easy way for us to examine "large" Block Diagrams.
To help us help you, please provide the following:
Are you using anything like a Producer/Consumer design to handle the Data I/O? What is your data rate? How are the data getting from the "Generation" part of the code to the "Save It Away" part? We (and by "we", I mean "I", at least) really need to see real code on a real screen that I can move around to "see it all") to help you figure this out.
Bob Schor
02-11-2025 10:50 PM
Dear Bob_Schor,
Thank you for your response.
I initially signed up for the forum when I was an undergraduate, but I haven’t actively used LabVIEW for a long time. Recently, however, it has become essential for my measurements, so I am working on improving my understanding.
I would consider myself a beginner in LabVIEW. I am familiar with basic structures such as for loops, mathematical operations, file read/write functions, and integrating subVIs from measurement devices (e.g., SR830, Keithley, etc.). However, I lack in-depth knowledge of more advanced topics like the ones you mentioned.
Before attaching my actual code, I have a few additional questions:
I appreciate your guidance, and I will attach the real code once I understand how to package it correctly.
02-12-2025 04:58 AM
I see lots of .Net nodes, returning references every single time, but not one single Close Node!
Each .Net reference created through a Constructor node or returned as a sub reference by a property or method node, allocates a LabVIEW memory block to maintain the underlaying .Net object reference. If you just let the according wire end in thin air, this object still remains in memory. On the next iteration you create again an object and call nodes that return sub objects and so on. Every .Net refnum NEEDS to be explicitly closed after it is not needed anymore.
LabVIEW's managed contract works differently than a .Net contract. It can reuse its own native datatypes on every loop iteration if the compiler has determined with complicated rules that it is not needed anymore but it can NOT determine if that is the case for external resources such a .Net objects.
You need to help it with that. LabVIEW only automatically closes any refnum objects when the top level VI stops executing, but your VI keeps running in a loop, so new objects are getting created on every loop iteration but never closed.
Most likely you would not need to create new objects and retrieve new subobjects on every loop iteration but that requires a somewhat more structured approach with a real state machine architecture. Your current program is a big spaghetti mess.
02-12-2025 02:37 PM
Dear Rolf Kalbermatter
Thank you for your kind words.
I have simplified the program by using only the .NET reference and a for loop.
I attempted to explicitly close the .NET reference after each loop, but I am still noticing memory growth while the program is running.
I have attached the program for your review. There is no sub VI from other source expect for Kinesis-labview provide by the following URL (Kinesis® with LabVIEW)
Could you kindly take a look and provide any suggestions or improvements to address the memory growth issue?
Thank you in advance for your assistance.
02-12-2025 03:18 PM
The Close in the red rectangle should not be in there. You should match the number of closes with the number of Constructor nodes, respectively with Property nodes that return a refnum.
And the Build array nodes in the yellow rectangles will of course each create an ever growing array!
02-12-2025 06:14 PM
@rolfk wrote:
The Close in the red rectangle should not be in there. You should match the number of closes with the number of Constructor nodes, respectively with Property nodes that return a refnum.
And the Build array nodes in the yellow rectangles will of course each create an ever growing array!
In addition, each time the local variable "Time Array" runs a copy of the dataset is made. Local Variables create copies, can be okay for scalars, but nor ever growing arrays.
02-12-2025 10:54 PM
Thank you for your previous feedback.
I attempted to organize the process as you advised, but I am still observing memory growth and experiencing interval delays during the measurement. I'm not entirely sure if I implemented the changes correctly as per your suggestions.
Could you kindly take another look at this and provide further guidance?
I appreciate your assistance in advance.
02-13-2025 01:14 AM
Hi salsberry,
@salsberry wrote:
Could you kindly take another look at this and provide further guidance?
I appreciate your assistance in advance.
02-13-2025 02:49 AM - edited 02-13-2025 02:52 AM
@salsberry wrote:
Thank you for your previous feedback.
I attempted to organize the process as you advised, but I am still observing memory growth and experiencing interval delays during the measurement. I'm not entirely sure if I implemented the changes correctly as per your suggestions.
Could you kindly take another look at this and provide further guidance?
I appreciate your assistance in advance.
That's in parts better but in terms of handling those references it is an utter "making matters worse"!
When I said property nodes that return a refnum I did not mean the "duplicate refnum out" terminal but refnums returned in the body of the property or method node (both green nodes do return a refnum as property value).
The red Close nodes are all utter nonsense and in fact should make your program fail completely to communicate with your device. The green Close node properly closes the refnum returned by the Device property node, but you just let the refnum from the Create Device method node flow into thin air to be never used and never closed. In fact the Create Device refnum should be already fine, you should not need to retrieve another copy of that just created refnum to use it.
The KCube Stepper Control refnum SHOULD NOT be closed in this VI ever. Somewhere you do create that refnum unless its a static .Net reference and that somewhere you should also close it. Proper software design is also about trying to manage resources in a way that they are allocated and deallocated in the same part of your program as much as possible. Don't create it in your startup routine, then try to figure out in which sub part of your program you need to deallocate it. You will soon end up in a complicated
if (condition X) but not (condition Y) except when (condition Z) but not (when my cat takes a nap) and (there is full moon)
deallocate this resource!
Still able to understand when it should be done and when not?
Exactly! You can't and neither can I nor do I want to understand.
But by handling allocation (creation) and deallocation in the same logical level of your program, you can avoid this type of involved conditionals almost completely.
This means that in this VI you need to close the two references returned by the Create Device method node and the Device property node exactly once each in every iteration, since they got created once. Of course the Device property node is almost certainly unnecessary since you already get a Device refnum to use from the Create Device method.
And then comes the next level: Why create a new device in every iteration? This should almost certainly be outside the loop (and the according close refnum too) unless the device driver for your hardware is a total fart from some software programmer who better should have stayed planting potatoes instead.