AnsweredAssumed Answered

Severe memory leak in libiio C# binding code

Question asked by tombomb on Jul 9, 2014
Latest reply on Jul 10, 2014 by DNechita

It looks like there is a fairly severe memory leak in the channel.cs file of the C# libiio binding code. The following code pins an array for use over the managed/native interop interface using GCHandle.Alloc(). However, GCHandle.Free() is never used to unpin the array, so each call the read() or write() causes the allocated array to stay pinned in memory and the .Net garbage collector cannot clean it up. For large acquisitions, the amount of memory leaked is substantial (i.e. gigabytes).

 

    public byte[] read(IOBuffer buffer, bool raw = false)
    {
        if (!is_enabled())
            throw new Exception("Channel must be enabled before the IOBuffer is instancied");
        if (is_output())
            throw new Exception("Unable to read from output channel");

 

        byte[] array = new byte[(int) (buffer.get_samples_count() * sample_size)];
        MemoryStream stream = new MemoryStream(array, true);
        IntPtr addr = GCHandle.Alloc(array, GCHandleType.Pinned).AddrOfPinnedObject();
        uint count;

 

        if (raw)
            count = iio_channel_read_raw(this.chn, buffer.buf, addr, buffer.get_samples_count() * sample_size);
        else
            count = iio_channel_read(this.chn, buffer.buf, addr, buffer.get_samples_count() * sample_size);
        stream.SetLength((long) count);
        return stream.ToArray();

 

    }

 

    public uint write(IOBuffer buffer, byte[] array, bool raw = false)
    {
        if (!is_enabled())
            throw new Exception("Channel must be enabled before the IOBuffer is instancied");
        if (!is_output())
            throw new Exception("Unable to write to an input channel");

 

        IntPtr addr = GCHandle.Alloc(array, GCHandleType.Pinned).AddrOfPinnedObject();
        if (raw)
            return iio_channel_write_raw(this.chn, buffer.buf, addr, (uint) array.Length);
        else
            return iio_channel_write(this.chn, buffer.buf, addr, (uint) array.Length);
   

}

 

Can we get this fixed?

Outcomes