Case study · ~2016
The memory leak that wasn't a memory leak.
A production test bench for a major automaker was crashing every two hours. The integrator's legal team was preparing to push the contractual penalty onto NI. I went on the follow-up site visit.
1
Legal claim averted
3
Runtimes profiled in parallel
~7h
To reproduce on-site
A test bench and a legal dispute.
A large German test-equipment integrator had built an end-of-line tester for a new generation of combustion engines at a major European automaker. The architecture was typical for the era: a C# / .NET application layer for the operator UI, LabVIEW test steps called in TestStand, and DLL bindings for third-party vendor technologies on all sides.
The bench leaked memory. Every two to four hours, the process would grow until it crashed. The automaker was claiming contractual penalties. The integrator's legal team had begun building a case that the leak originated inside LabVIEW's runtime, and that the penalty should be transferred to NI.
A senior NI engineer had already been to the site and walked into an ambush: the customer's legal counsel was waiting in the meeting room with a pre-drafted letter acknowledging the fault "could be" NI's. NI's engineer was requested to sign it. He did not. The follow-up visits were reassigned in pairs. I was designated for the next one, in my capacity as Application Engineer Group Manager and for my knowledge of .NET interop.
Two runtimes, one process.
LabVIEW and C# don't compile to machine code. They execute inside runtimes (the LabVIEW Run-Time and .NET's Common Language Runtime), each with its own memory manager. When the application binds third-party DLLs across both environments, allocations can live in three regions: LabVIEW-managed, .NET-managed, and unmanaged native heap. If the leak was in LabVIEW's collector, it was a product defect. If it was anywhere else, it wasn't.
Identifying which, and proving it, was the question.
Split the profiling, compare the shapes.
-
Divide the runtimes between us.
My colleague profiled LabVIEW-internal allocations with NI's tools (Profile / Performance / Memory, the Desktop Execution Trace Toolkit). I took the .NET side: Windows PerfMon, Sysinternals RAMMap, JetBrains dotTrace and dotMemory. Two engineers, two instrumentation stacks, one dataset.
-
Reproduce under production conditions.
On-site, with a real engine loaded on the bench and all simulation algorithms disabled, we triggered the leak in the first hour. The aggregate process memory was climbing steadily, but neither LabVIEW's memory manager nor .NET's garbage collector held the growing region. The leak lived in unmanaged memory.
-
Walk every unmanaged allocation.
Most were fine: hardware handles, bounded task-configuration objects, pointers that closed on scope exit. The exception was the vision subsystem. LabVIEW IMAQ image references and acquisition sessions were being passed to a proprietary C# vision algorithm, processed, and returned to TestStand, without explicit
closecalls on either side. Because the images lived in shared memory between the two runtimes, neither collector would touch them. -
Patch locally, verify the trajectory.
We added explicit
IMAQ Closecalls in a handful of sub-VIs, re-ran the bench, and watched the growth rate slow by roughly 20%. Not a fix, but enough to place the root cause on the customer side. The vision pipeline still needed a proper re-architecture, but that was now a scoped engineering project, not a contractual dispute.
What it cost, what it saved.
Root cause: improper handle management in the customer's vision subsystem. Not a LabVIEW defect. The claim against NI was dropped. The integrator and the automaker settled directly; the terms weren't shared with us.
The bench still required a daily restart until the integrator re-architected the vision pipeline. That project later went to one of the software engineers I had recruited and hired out of university a year earlier. A small piece of the team I was building at NI paying itself forward.
The meeting is what stays with me. A pure salesperson signs the letter or walks out. A pure engineer finds the leak but can't read the room. The role I was in asked for both: the depth to profile the memory, and the composure to recognise when the pressure in the room was trying to substitute for data.
Other case studies
Absorbing NI's DACH distribution, growing it into a €30M BU . The business counterpart to this technical one.