Python: утечка памяти

Я использую Python для отображения растрового изображения на ЖК-дисплее (Raspberry Pi). Это работает довольно хорошо, но кажется, что я создал себе огромную утечку памяти. Этот фрагмент кода кажется виновником:

def displayBitmap(self):
    spi.open(0,0)
    f = open("data/565.bmp", "rb")
    imgdata = f.read()
    f.close()

    self.setAddress(0, 0, LCD_WIDTH-1, LCD_HEIGHT-1)
    k = 0
    for i in range(0, (LCD_WIDTH*LCD_HEIGHT)):
        dt = (ord(imgdata[k]) | (ord(imgdata[k+1]) << 8))

        self.spiOutData(dt,2)
        k +=2
    imgdata = None
    spi.close()

...

def spiOutData(self, data, bytes=1):
    io.digitalWrite(15, io.LOW)
    io.digitalWrite(16, io.HIGH)

    io.digitalWrite(self.dcPin, io.HIGH)

    if (bytes == 1):
        spi.xfer2([(data)])
    else:
        spi.xfer2([(data>>8)])
        spi.xfer2([(data)])

Некоторое время работает нормально, но в какой-то момент останавливается из-за нехватки памяти. Я предполагаю, что содержимое imgdata никогда не удаляется, но мои знания Python, похоже, слишком плохи, чтобы найти причину. Не могли бы вы дать мне подсказку, пожалуйста? Большое спасибо.


person tungl    schedule 03.02.2014    source источник
comment
imgdata = None это совершенно бесполезно. У Python есть собственный сборщик мусора, который действительно знает, как выполнять свою работу. Когда функция завершает работу, эта ссылка все равно будет удалена, так что такого рода операторы имеют единственный эффект немного замедления вашего кода. Возможно, данные в imgdata не освобождаются, но вы можете быть на 100% уверены, что это не ошибка этой ссылки. Могут быть и другие части вашей программы, которые каким-то образом захватывают ссылку на нее (хотя это и странно). -1 за отсутствие полной трассировки.   -  person Bakuriu    schedule 03.02.2014
comment
Спасибо за Ваш ответ. Я так и думал и добавил imgdata = None только в целях тестирования, потому что, как я уже сказал, я совершенно невежественен. Вот весь код, но то, что я опубликовал, на самом деле почти все, что происходит: nopaste.info/9c65fb9840.html /a> Я не могу предоставить трассировку прямо сейчас, так как для заполнения памяти требуется довольно много времени, но я предоставлю ее, как только это произойдет снова.   -  person tungl    schedule 03.02.2014
comment
Для тех, кто сталкивается с той же проблемой: похоже, это связано с ошибкой в ​​​​библиотеке spidev. (Вызов spi.xfer2 вызывает утечку памяти)   -  person tungl    schedule 03.02.2014
comment
Если вы уверены в этом, вы должны опубликовать свой собственный ответ и принять его.   -  person Bakuriu    schedule 03.02.2014


Ответы (1)


Итак, вот что я выяснил:

  • модуль py-spidev (или какая-то часть самого spidev) кажется проблемой.
  • помимо утечки памяти, py-spidev невероятно медленный

Теперь я избавился от py-spidev и пишу в /dev/spidev0.0 напрямую через дескриптор файла. Больше не требуется чрезмерного использования памяти, а для обмена данными по SPI теперь требуется около двух секунд, что составляет примерно десятую часть того времени, которое требовалось раньше.

person tungl    schedule 03.02.2014
comment
Эта ошибка, кажется, устранена в версии 3.5 пакета spidev с этим изменением: github. com/doceme/py-spidev/pull/57/files - person alu; 29.01.2021