Identifying and Resolving Memory Growth Issues in TestStand Systems

Overview

When investigating unwanted memory growth in a TestStand system, it is important to begin by narrowing down the issue to a small set of TestStand steps or code modules that can be examined at a closer level for potential causes of the memory growth. This document describes techniques for identifying such issues within test code and introduces tools that can be used to further investigate memory growth issues within common code module development environments. This document covers potential memory issues that you may encounter in test sequences as well as in LabVIEW, LabWindows/CVI, or .NET code modules.

Contents

TestStand Sequences

If you have eliminated all code modules from your test sequence and still see memory growth during the test system execution, settings within TestStand itself may be contributing to the memory growth. There are several reasons why TestStand could be causing memory growth.

Result Collection and Report Generation

One of the most common contributors to memory growth in TestStand systems is the result collection and reporting process. If result processing and report settings are not configured to conserve memory, you may see memory growth as test results are collected and retained in memory. In test sequences which execute for a long period of time or generate a large number of results, this can eventually result in an out-of-memory error.
For information on configuring result collection and reporting settings in TestStand to optimize memory issues, refer to the Addressing Memory Issues with Report Generation in TestStand document.

Object, File, and Device References

As a test system executes, variables are commonly used to store references to files, hardware devices, or TestStand PropertyObjects for use by steps in the test sequence. If these references are not properly released when they are no longer needed, the TestStand process will retain these objects in memory. If the reference is not released when the execution has completed, a reference leak may occur. This can cause memory to continue to grow as the test system is executed multiple times.

To identify whether memory growth is occurring as a result of references not being released properly, inspect the test sequence to determine where references are being opened and closed. This will help ensure that any references opened are being properly closed before the test sequence completes execution. If you are passing references into code modules, you may also use memory profiling tools within the code module environment to determine whether references are being closed properly.

When using the TestStand API within your test sequence or a code module, it is common to create references to sequence files, sequences, or other TestStand objects. When you create a reference to a TestStand object, you must release the reference before the execution completes. If you do not release a TestStand reference properly, you may see a PropertyObjects Were Not Released warning dialog when you exit the TestStand Sequence Editor or your user interface. This dialog will often indicate the type of TestStand reference that is being leaked, which may allow you to locate the reference that is not being released.

You must enable the Report Object Leaks feature in TestStand to see the warning dialog when a reference has not been released properly. Complete the following steps to enable the dialog:

  1. Click Configure » Station Options and navigate to the Preferences tab.
  2. Click the Debug Options button.
  3. Enable the checkbox for the Report Object Leaks option.

Note that the PropertyObjects Were Not Released warning dialog does not list reference leaks in the following adapter code modules:

  • In LabVIEW VIs, because LabVIEW automatically releases leaked references when the LabVIEW adapter unloads the VI, which occurs before a TestStand application exits.
  • In .NET assemblies, because TestStand releases the .NET app domain used by executions before a TestStand application exits.

Using Variables to Store Large Data Sets

Memory growth can also occur in TestStand if the test sequence is using variables to store large amounts of data in a container or array. If your test sequence is storing measurements or other large sets of data in TestStand variables, consider modifying the test sequence to store this data in another location such as in a file stored on disk.

LabVIEW Code Modules

If you have narrowed down the memory growth to a LabVIEW code module, you will need to use the LabVIEW Development System to inspect the LabVIEW code for potential causes of memory growth. Specific strategies for investigating memory growth issues in LabVIEW code are covered in the Investigating Memory Growth Issues in LabVIEW Code Modules Called from TestStand document.

LabWindows/CVI Code Modules

If you have narrowed down the memory growth to a LabWindows/CVI code module, you can use the LabWindows/CVI development environment to inspect the code for potential causes of memory growth.

Causes of Memory Growth in LabWindows/CVI Code

The C programming language requires the code module developer to handle memory management. For this reason, a programming error can result in unexpected memory growth as the code module executes. In many cases a code module may compile and execute with no apparent runtime errors, but may not release references or allocated memory space properly.

As you investigate a CVI code module which is exhibiting unwanted memory growth, you should pay specific attention to areas in the code where references are created or memory is allocated. This will help to ensure that these references are released and memory is deallocated before the code module completes execution.

LabWindows/CVI Resource Tracking Window

The Resource Tracking Window is a tool provided in the CVI development environment which displays memory allocations and deallocations to allow you to determine whether memory is being released as the code module executes. The tool can track a wide variety of memory allocations; a complete list of the resources that can be tracked by the tool is available in the LabWindows/CVI Help.

For more information about using the Resource Tracking Window to investigate memory growth in CVI, please refer to the Detecting Memory Leaks in LabWindows/CVI Code Modules called from NI TestStand document.

.NET Code Modules

If you have narrowed the memory growth to a .NET code module, you can use Microsoft Visual Studio or a similar .NET programming environment to inspect the code for potential causes of memory growth.

Causes of Memory Growth in .NET Code Modules

Although the .NET Framework implements a garbage collector to release memory when it is no longer needed, memory usage can still grow as a .NET code module executes. Since the garbage collector can only release memory when it is no longer being used by any objects in the .NET code, memory usage may grow if references are created and not released as the code is executed. For more information on potential causes of memory growth in .NET code, please see this Microsoft KnowledgeBase article.

TestStand Step Settings for .NET Code Modules

If the .NET code module is being called directly from a TestStand step, you should ensure that any .NET objects created by the step are being released properly. When a step using the .NET adapter creates a new instance of an object, the object reference return parameter includes a Dispose checkbox. In cases where the TestStand sequence is the owner of the object, this checkbox should be enabled to ensure that the object is disposed properly once all references to it have been released. For more information on this step setting, please refer to the TestStand Help.

Additionally, if your test sequence is maintaining a reference to a .NET object, TestStand will be unable to release the .NET object from memory until all references have been released. For a long-running test sequence where multiple .NET objects are created, this could result in memory growth. You can release a reference variable which is referring to a .NET object by setting the variable to Nothing. Once all references to the object have been released, the .NET garbage collector will be able to release the object from memory.

Tools for Investigating .NET Memory Growth

There are several tools available for investigating memory growth in .NET code.

  • Microsoft Visual Studio -- The Visual Studio development environment provides tools to gather information on memory usage in a .NET application. These tools allow you to profile memory usage as your .NET code executes, which can help you determine where memory growth may be happening in your code. For more information on these tools, see this blog post on MSDN.
  • .NET Memory Profiler -- The .NET Memory Profiler is a third-party tool that allows you to take a snapshot of all .NET objects in the memory of a process, which can help you determine whether .NET objects are remaining in memory for a long period of time. You can find more information on the .NET Memory Profiler at http://memprofiler.com/.

Conclusion

Once you have narrowed down a memory growth issue to a small set of code, the most effective way to investigate the issue is to examine the TestStand sequence and code modules directly. The suggestions in this document should serve as a starting point in debugging and describe several potential causes for memory growth in test systems. By carefully inspecting the code for these issues and using the tools provided to you within the code module development environment, you can identify and resolve these issues to reduce or eliminate memory growth in your test system.

Was this information helpful?

Yes

No