使用Yocto的Python内存泄漏

时间:2015-10-01 07:59:00

标签: python memory-leaks yocto

我在覆盆子pi上运行python脚本,不断检查Yocto按钮,当它被按下时,它会将来自不同传感器的数据放入数据库中。

持续运行的代码片段是:

#when all set and done run the program
Active = True
while Active:
    if ResponseType == "b":
        while Active:
            try:
                if GetButtonPressed(ResponseValue):
                    DoAllSensors()
                    time.sleep(5)
                else:
                    time.sleep(0.5)
            except KeyboardInterrupt:
                Active = False
            except Exception, e:
                print str(e)
                print "exeption raised continueing after 10seconds"
                time.sleep(10)

GetButtonPressed(ResponseValue)如下所示:

def GetButtonPressed(number):
    global buttons
    if ModuleCheck():
        if buttons[number - 1].get_calibratedValue() < 300:
            return True
    else:
        print "module not online"
    return False


def ModuleCheck():
    global moduleb
    return moduleb.isOnline()

我不太确定可能出现的问题。但RPI耗尽内存大约需要一个小时。

内存不断增加,每15分钟左右按一次按钮。

这已经告诉我问题必须出现在上面显示的代码中。

1 个答案:

答案 0 :(得分:0)

问题是 yocto_api.YAPI 对象将继续在 _DataEvents dict(类范围属性)中累积 _Event 对象直到你打电话给 YAPI.YHandleEvents 。如果你没有使用API​​的回调,很容易想到(我做了几个小时)你不需要调用它。 API文档在这一点上并不清楚:

  

如果您的程序包含重要循环,您可能希望包含对此函数的调用,以确保库负责处理通信通道上模块所推送的信息。这不是绝对必要的,但它可以提高库的反应性以用于以下命令。

在我决定在我自己的代码中定期轮询传感器之前,我做了一些API级回调,并且可能会在其中启用一些设置,导致这些事件累积。如果不是这样的话,我无法想象为什么他们会说 YHandleEvents 是“非常必要的”,除非他们在瑞士制造无限RAM的ARM设备。

无论如何,这是你定期召唤的神奇静态方法。我每五秒就这样做一次就是在没有加载系统的情况下解决问题。积累不需要的事件的API代码仍然闻到我的气味,但现在是时候继续前进了。

#noinspection PyUnresolvedReferences
@staticmethod
def HandleEvents(errmsgRef=None):
    """
    Maintains the device-to-library communication channel.
    If your program includes significant loops, you may want to include
    a call to this function to make sure that the library takes care of
    the information pushed by the modules on the communication channels.
    This is not strictly necessary, but it may improve the reactivity
    of the library for the following commands.

    This function may signal an error in case there is a communication problem
    while contacting a module.

    @param errmsg : a string passed by reference to receive any error message.

    @return YAPI.SUCCESS when the call succeeds.

    On failure, throws an exception or returns a negative error code.
    """
    errBuffer = ctypes.create_string_buffer(YAPI.YOCTO_ERRMSG_LEN)

    #noinspection PyUnresolvedReferences
    res = YAPI._yapiHandleEvents(errBuffer)
    if YAPI.YISERR(res):
        if errmsgRef is not None:
            #noinspection PyAttributeOutsideInit
            errmsgRef.value = YByte2String(errBuffer.value)
        return res

    while len(YAPI._DataEvents) > 0:
        YAPI.yapiLockFunctionCallBack(errmsgRef)
        if not (len(YAPI._DataEvents)):
            YAPI.yapiUnlockFunctionCallBack(errmsgRef)
            break

        ev = YAPI._DataEvents.pop(0)
        YAPI.yapiUnlockFunctionCallBack(errmsgRef)
        ev.invokeData()
    return YAPI.SUCCESS