0

I am using ZeroMQ in C# language. It is throwing following error:

OutOfMemoryException: zmq_msg_init_size

Below is the code snippet:

private void onDataArrived(object sender, DataArrivedEventArgs e)
{
    // receive the data in the form of bytearray
    var message = new ZMessage{ new ZFrame(bytearray) };

    publisher.Send(message);
}

The onDataArrived is a callback function. The publisher is defined in class constructor as follows:

zmqContext = new ZContext();
publisher = new ZSocket(zmqContext, ZSocketType.PUB);
publisher.Bind("tcp://*:9001"); // Using depth data port

Any suggestions?

Do I need to destroy the message?

Please note that I just want to send the bytearray. Since I don't know the best way, I created ZFrame and ZMessage objects.

Inside the Visual Studio Debugger, I noticed that Process Memory is keep on increasing and going up to 4 GB. The error is being thrown at this moment.

user3666197
  • 1
  • 6
  • 50
  • 92
ravi
  • 6,140
  • 18
  • 77
  • 154
  • 1
    How have you declared/initialized bytearray? Is it empty? If you you look at the implementation of ZFrame (https://github.com/zeromq/clrzmq4/blob/master/ZFrame.cs), it will throw the above exception under certain circumstances when the ZFrame is constructed. – Kerri Brown Nov 23 '17 at 10:48
  • @KerriBrown: Basically the byte array is created inside the `onDataArrived` callback function. I checked the length of `bytearray`. It is around 4,700,000 bytes. – ravi Nov 23 '17 at 12:04
  • @mjwills: No I am not. I am not aware of it. I just initialized `zmqContext` and `publisher` as shown above. Then I am using `publisher` to send `message` as shown in the callback function. Please note that, I just want to send the `bytearray`. Since I don't know the best way, I created `ZFrame` and `ZMessage` objects. – ravi Nov 23 '17 at 12:07
  • @mjwills: I just added my observation in the post. Please check the bold text in the post. – ravi Nov 23 '17 at 12:10
  • 1
    That is because you aren't calling `Dispose`. – mjwills Nov 23 '17 at 12:11
  • Yes. You are absolutely right. I added `message.Dispose()` after `publisher.Send(message)` and it worked. The Process Memory is not going more than 80 MB now, Thank you very much. Could you please explain and give the answer so as to close this question? – ravi Nov 23 '17 at 12:11

1 Answers1

2

ZFrame implements IDisposable. As a general rule, you should Dispose of IDisposable objects when you are 'finished' with them.

It is particularly important with ZFrame since it contains a DispoIntPtr (pointer to unmanaged memory).

Without the Dispose call, it will not be freed in a timely manner. See https://github.com/zeromq/clrzmq4/blob/master/ZFrame.cs :

protected override void Dispose(bool disposing)
{
    if (framePtr != null)
    {
        if (framePtr.Ptr != IntPtr.Zero)
        {
            Close();  // <- cleanup happening here
        }
    }
    GC.SuppressFinalize(this);
    base.Dispose(disposing);
}
mjwills
  • 23,389
  • 6
  • 40
  • 63