Zeromq 内存泄漏 (pyzmq)

Posted

技术标签:

【中文标题】Zeromq 内存泄漏 (pyzmq)【英文标题】:Zeromq memory leak (pyzmq) 【发布时间】:2012-12-04 05:35:11 【问题描述】:

您好,我正在尝试使用 ZeroMQ 使用呼吸机/工作人员/接收器模式发送大数据包。

我尝试添加工人。每次,sink 进程内存使用量都会增加一点。然后它在大约 6 或 7 名工人时达到一个临界点,内存突然呈指数增长,直到它消失:

> *** error: can't allocate region
> *** set a breakpoint in malloc_error_break to debug Assertion failed: (msg_->flags | ZMQ_MSG_MASK) == 0xff (zmq.cpp:211)
> Python(42410,0xaccb8a28) malloc: *** mmap(size=3559424) failed (error
> code=12)

这是代码(仅显示工人/接收器模式):

import sys
import resource
import zmq
import time

context = zmq.Context()


if sys.argv[1] == 'worker':
    # Socket to send messages to

    sender = context.socket(zmq.PUSH)
    sender.connect("tcp://localhost:5558")

    while True:
        msg = 'x' * 3559333
        time.sleep(.01)
        sender.send(msg)
else:
    # Socket to receive messages on

    receiver = context.socket(zmq.PULL)
    receiver.bind("tcp://*:5558")
    while True:
        msg = receiver.recv()

        print msg[0:5], len(msg), resource.getrusage(resource.RUSAGE_SELF).ru_maxrss

这仅仅是缺乏硬件资源吗?数据积压?或者有没有办法避免这种情况?

我正在运行具有 16gb 内存的 OSX Mountain Lion 和具有 zmq 2.2.0.1 的 Python 2.7。

谢谢

【问题讨论】:

【参考方案1】:

这仅仅是缺乏硬件资源吗?

好吧,让我们算一下。每个工作人员每 10 毫秒发送 3.3MB。或大约每秒 300mb。现在你添加了更多的工人。当您最多有 5 个工作人员时,您每秒发送大约 1.5GB。

我认为您已经找到了机器的性能限制。当 sink 进程与所有工作进程在同一台机器上运行时,它每秒能够消耗 1-2GB 之间的数据。当数据进入的速度快于接收器进程中队列的建立速度快于它们被清空的速度时,您就会耗尽内存。

或者有没有办法避免这种情况?

发送较小的消息?不那么频繁? :) 或者将工人和接收器进程放在不同的机器上。请记住,工作人员正在从接收器中窃取 CPU 资源。如果这是一台四核机器,那么在接收器加上最多 3 个工作人员的情况下,操作系统可能会将几乎所有的处理器核心分配给每个进程。

一旦添加了第 4、5、6 个 worker,操作系统就无法将 100% 的核心分配给任何进程。他们必须开始共享,因此即使消息速度加快,接收器也会变慢。这可以解释您所看到的内存使用量呈指数增长的临界点。

嗯 - 这表明了一个有趣的实验。你能配置你的mac,让sink进程以非常高的优先级运行吗?这可能会带来更好的结果。我自己从未尝试过,但请参阅以下链接以获取想法...https://discussions.apple.com/thread/1491812?start=0&tstart=0

【讨论】:

谢谢。我尝试了 nicing 并没有帮助,但是是的,它一定是缺乏网络。正如你所说,我可能会沉在一个单独的盒子上。如有必要,我什至可能有多个水槽。 这确实表明我最好不要将其传播到多个盒子上。相对于网络传输限制,计算时间太少了。我最好在 ec2 上获得这 20 个计算单元盒中的一个并在那里完成所有工作。我想知道这种情况发生的频率有多高,在一个将 hadoop 作为所有此类任务的解决方案出售的世界中。 这当然比上面的要多,但也不过是在制表符分隔的文本上进行拆分以及一些计数和过滤。 我试着让工人拥有最低的优先级。它没有帮助 另请注意,ZeroMQ:s 队列默认设置为 1000。如果一个缓冲区填满了 3.3 MB 的消息大小,那就是 3.3GB。每个发布者为每个订阅者保留一个单独的队列,这意味着您在这里很快就会用完内存。队列大小是可调整的。我不确定 Sink 是否为每个传入的工作人员保留一个队列,但这很可能。

以上是关于Zeromq 内存泄漏 (pyzmq)的主要内容,如果未能解决你的问题,请参考以下文章

c++ 内存泄漏问题

MFC内存泄漏调试

如何防止java中的内存泄漏

记录一次DialogFragment 内存泄漏

常见的内存泄漏原因及解决方法

Android ValueAnimator --内存泄漏