我正在尝试使用Windows 10 64位操作系统中的ZeroMQ传输大量字节(大小:12兆字节)。传输速率约为每秒15帧。
代码抛出以下错误:
Exception thrown: 'System.OutOfMemoryException' in ZeroMQ.dll
在使用Visual Studio进行调试期间,它显示4GB进程内存,如下面的屏幕截图所示:
然而,当我检查操作系统中的内存消耗时,它显示了8GB的7.1GB。但是仍然没有使用801MB,这让我想知道System.OutOfMemoryException
异常。
见屏幕截图:
电脑配有千兆以太网卡。请参阅以下卡片使用情况:
请参阅下面的代码:
ZContext zmqContext;
ZSocket publisher;
Stopwatch watch;
readonly byte[] longByteArray = new byte[12000000];
Program()
{
zmqContext = new ZContext();
publisher = new ZSocket(zmqContext, ZSocketType.PUB);
publisher.Bind("tcp://*:11111");
var timer = new Timer();
timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
timer.Interval = 1000.0 / 15;//15 FPS
timer.Enabled = true;
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
var frame = new ZFrame(longByteArray);
publisher.Send(frame);
frame.Dispose();
}
以下是我的观察:
我的问题如下:
答案 0 :(得分:1)
最好不要依赖静态数字。每个JUMBO消息(如上所述)必须存储在几个地方,其中一些位于ZeroMQ控制域之外(通常是O / S和驱动器缓冲器)。当然,ZeroMQ在可能的情况下在零拷贝方面做得很好,但是将数据注入网络通常是一个O / S工作,因此任何自由空间在Mammoth大小的数据块上都“快速消失”(我是比方说,ZeroMQ可以提供整个,无论大小的数据块,还是什么都没有?)。
接下来,有 Context
级实例设置(高水位标记和其他)明确警告不依赖于XYZ [B]
免费且可用于消息数据如果设置了XYZ [B]
的非常值 - 由于任何内部缓冲管理技巧,API文档和注释会促使预期2/3以下的任何内容,如果不是该设置的1/2,则实际可用于任何与消息相关的数据(未提及,如果碰巧有超过一个.connect()
对象的话,缓冲空间“消费”会发生什么?
( 1-sends : {2,3,4,...}-receive )
这个有一个干净的解决方案。它通常不仅适用于快速视频流,而且通常适用于任何过程监控,非刚性传感器网络甚至音频流,其中目标处理不需要“听到”数据的每个片段-flow,但会欣赏继续冲浪TimeDOMAIN演变的“前波”(获取相当最新的数据,而不是因为没有收到之前的“旧”读数而哀悼):
使用 .setsockopt( ZMQ_CONFLATE, 1 );
方法,您就完成了!
如果确实需要获得最佳性能(并且如果端到端延迟允许)尝试数据压缩步骤的效果(移动“更少”字节,在增加的本地/远程权衡时处理工作负载)并且可以尝试移动一组“独立”处理/传输的“拆分”数据块,其中多个Context( <_nIOthreads_> )
实例IO线程可以提供多个Socket
上的较小块的几乎并行传输 - 实例(IO线程可以在本地/远程端进行负载平衡,
再次使用 .setsockopt( ZMQ_AFFINITY, <_IOthreadORD#_> )
-method
最后,但并非最不重要的是,如果延迟抖动对于QoS至关重要,我也会尽力控制 .setsockopt( ZMQ_TOS, <_TOS#_> )
进行TypeOfService端到端控制。