Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Memory leak AnalogWaveform when data not processed properly / in due time?

I have an application issue that I need a bit of help with 🙂

 

I am reading a lot of data - roughly 1msps, and things are fine when testing on hardware without stressing the application. However, when my process is running for real then there is so much going on that I sometimes miss a bit of data - which is NOT a problem for me.

 

The error is basically:

NationalInstruments.DAQmx.DaqException: Attempted to read samples that are no longer available. The requested sample was previously available, but has since been overwritten.

 

Now, there seems to be some sort of memory leak when this occurs, and after a short while of real running then I end up with out of memory exceptions:

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
   at NationalInstruments.AnalogWaveform`1.GetRawData()
   at Strecon.Drivers.NI.NI9223.AnalogInCallback(IAsyncResult ar)

Is there some special cleanup calls that I can insert into my application (analog callback below)

 

try
            {
                if(myTask != null && myTask == ar.AsyncState)
                {
                    // Read data from channel
                    NationalInstruments.AnalogWaveform<double> data;
                    data = analogInReader.EndReadWaveform(ar);
                    
                    // Check for and report any overloaded channels
                    
                    // Store data
                    //RawData.Enqueue(data);
                    double[] rawdata = data.GetRawData();
                    vdaStrainDataValues.SetValue(rawdata, DateTime.Now);
                    
                    // Continue sampling
                    analogInReader.BeginMemoryOptimizedReadWaveform(samplesPrFrame, analogCallback, myTask, data);
                }
            }
            catch(Exception ex)
            {
                log.Warn("Exception in callback", ex);
                ModuleStop(); //My stop start stuff
                ResponseObject ro = ModuleStart();
            }

 

Btw. I am on 32 bit (I have one external HW driver that is not available as 64bit) and NI-DAQmx is 9.7.0f0

I am not 100% sure that there is something wrong with NI-DAQmx, but it is certainly where it manifests itself in my app 🙂

 

Help / suggestions is greatly appreciated.

0 Kudos
Message 1 of 4
(5,222 Views)

Hi Larover88

 

First let me explain the error you get. So when you start you data acquisition with X number of samples to read per Y number of seconds then there is allocated a buffer to keep your data values. If you wait long enough with reading out the data values there is not enough room in the buffer to store all the values and you get a buffer overflow. In this case it is shown because you try to read some values that is deleted due to the overflow.

 

My best recommendation is to keep your data acquisition in a seperate thread in your application and make sure you don't do anything else in that thread. 

 

You should be able to run you DAQ application at a fairly equal loop rate, if you put analysis and maybe also file i/o into this thread there will be a lot of factors that can make the loop slow down and give you a buffer overflow.

 

So I would do the following:

 

Main program:

StartDAQThread();

StartAnalysisLogThread();

While(Stop == false) {

}

SignalStopToThreads();

WaitOnThreadsToComplete();

 

StartDAQThraed:

Loop with 100hz {

Read array of values from DAQ 

Store array of values in a Queue

}

 

StartAnalysisLogThread:

While{

if (no values in queue)

      Wait for new values in queue

else (values in queue)

     Read out values from queue

     Process values i.e. with FFT

     Log Results

}

 

 

 

The sole purpose of this is to move the buffered values from the small memory on the actual DAQ device and into the large memory we have on the PC. To not get errors we need to have a fairly constant rate when reading the DAQ, and to get this we isolate the DAQ tasks in a single thread. If the AnalysisLogThread is slow sometimes the memory will just build up on the PC but that is no problem (unless it is always too slow to process the data coming in). 

 

This structure is called Producer Consumer structure. It is a design pattern you see in both C++, C#, LabVIEW, Java and many other programming languages. Meaning if you want some inspiration and examples for doing this online just google "producer consumer <<insert programming language>>".

 

 

Best Regards

Anders Rohde

Applications Engineer

National Instruments Denmark

Message 2 of 4
(5,209 Views)

Hi,

 

Is there an actual c# or vb.net example of this process using a simple DAQMx analogue multi channel read?

 

It would be very helpful.

 

 

Regards

 

Steve

0 Kudos
Message 3 of 4
(5,153 Views)

Thank you for the reply Anders.

 

It is actually already running in a separate thread, however there is no guarantee in .NET that the thread will get CPU time.

When it (the exception) occurs (and it always will at some point in time in .NET) then I saw some some memory not beeing released, and I suspected (and still do) that there is a memory leak somewhere in the NIDAQ framework that is triggered by this exception.

 

I reduced the problem by using two threads, one for sampling and one for processing, and then a lot of data copying.

 

I propose that you increase your input sample buffers to having n arrays for sample data instead of just one - circular buffer of arrays. Then I could allocate say 50 arrays of ½megabyte size and just follow the sample pointer in a separate thread. I don't care about the potential lag since this can be adressed in software...

 

Kind regards.

0 Kudos
Message 4 of 4
(5,152 Views)