2015-10-01 3 views
1

Я запускаю скрипт python на малине pi, который постоянно проверяет кнопку Yocto, и когда он нажимается, он помещает данные из другого датчика в базу данных.Утечка памяти 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

Использование Python, как бесформенный, чтобы определить, где утечка памяти идет http://smira.ru/wp-content/uploads/2011/08/heapy.html –

+1

Утечка была в Yocto библиотеке поэтому мне пришлось создать обходной путь, чтобы каждый раз его перезагружать, чтобы предотвратить его сбой, пока я не получаю другое решение. – Mickboe1

+0

Я чувствую, что это хороший день для сообщения об ошибках :) –

ответ

0

Проблема заключается в том, что yocto_api.YAPI объект будет продолжать накапливать _event объекты в его _DataEvents Dict (атрибут класса шириной), пока вы не вызовете YAPI.YHandleEvents. Если вы не используете обратные вызовы API, легко подумать (я делал в течение нескольких часов), что вам не нужно когда-либо называть это. Документы API не совсем ясны:

Если ваша программа включает в себя значительные циклы, вы можете включить вызов этой функции, чтобы убедиться, что библиотека выполняет информацию, модулей на каналах связи. Это не является строго необходимым, но это может улучшить реактивность библиотеки для следующих команд.

Я немного поработал с обратными вызовами уровня API, прежде чем я решил периодически опросить датчики в своем собственном коде, и вполне возможно, что в них активируется некоторая настройка, которая вызывает накопление этих событий. Если это не так, я не могу себе представить, почему они сказали бы, что звоните YHandleEvents «не является абсолютно необходимым», если только они не делают 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 
профилирование памяти
Смежные вопросы