Я уверен, что я страдаю от утечки памяти, но у меня нет 100% прибитых вниз, как это происходит.Потенциальная утечка памяти в моем приложении wxPython
Приложение Iv'e записывает 2 изображения с URL-адреса и ставит в очередь каждый набор изображений, называемый транзакцией, в очередь, которая выставляется пользовательским интерфейсом и отображается. Изображения довольно большие, в среднем около 2,5 МБ. Таким образом, чтобы ускорить пользовательский интерфейс и сделать его более отзывчивым, я предварительно загружаю изображения транзакций в объекты wxImage и сохраняю их.
Когда пользователь выталкивает другую транзакцию, я загружаю предварительно загруженное изображение в объект окна, который затем преобразует wxImage в растровое изображение, а DC - к окну. Затем объект окна отображается на панели.
Когда транзакция завершена пользователем, я уничтожаю объект окна (предположительно, окно уходит, как и растровое изображение), а структура данных транзакции перезаписывается «Нет».
Однако, в зависимости от того, сколько изображений предварительно загружено, задан ли размер очереди и все сделано за один раз, или я могу позволить небольшому размеру очереди сидеть со временем, он в конечном итоге сбой. Я действительно не могу позволить этому случиться. :)
Кто-нибудь видит какие-либо очевидные логические ошибки в том, что они делают? Собирает ли мусор python? У меня нет большого опыта работы с проблемами памяти.
это код;) Это код, связанный с потоком, который загружает изображения - он задан в основном потоке, запускает GUI - основная функция потока загрузки - это функция «fill_queue»:
def fill_queue(self):
while True:
if (self.len() < self.maxqueuesize):
try:
trx_data = self.download_transaction_data(self.get_url)
for trx in trx_data:
self.download_transaction_images(trx)
if self.valid_images([trx['image_name_1'], trx['image_name_2']]):
trx = self.pre_load_images(trx)
self.append(trx)
except IOError, error:
print "Received IOError while trying to download transactions or images"
print "Error Received: ", error
except Exception, ex:
print "Caught general exception while trying to download transactions or images"
print "Error Received: ", ex
else:
time.sleep(1)
def download_transaction_images(self, data):
""" Method will download all the available images for the provided transaction """
for(a, b) in data.items():
if (b) and (a == "image_name_1" or a == "image_name_2"):
modified_url = self.images_url + self.path_from_filename(b)
download_url = modified_url + b
local_filepath = self.cache_dir + b
urllib.urlretrieve(download_url, local_filepath)
urllib.urlcleanup()
def download_transaction_data(self, trx_location):
""" Method will download transaction data and return a parsed list of hash structures """
page = urllib.urlopen(trx_location)
data = page.readlines()
page.close()
trx_list = []
trx_data = {}
for line in data:
line = line.rstrip('|!\n')
if re.search('id=', line):
fields = re.split('\|', line)
for jnd in fields:
pairs = jnd.split('=')
trx_data[pairs[0]] = pairs[1]
trx_list.append(trx_data)
return trx_list
def pre_load_images(self, trx):
""" Method will create a wxImage and load it into memory to speed the image display """
path1 = self.cache_dir + trx['image_name_1']
path2 = self.cache_dir + trx['image_name_2']
image1 = wx.Image(path1)
image2 = wx.Image(path2)
trx['loaded_image_1'] = image1
trx['loaded_image_2'] = image2
return trx
def valid_images(self, images):
""" Method verifies that the image path is valid and image is readable """
retval = True
for i in images:
if re.search('jpg', i) or re.search('jpeg', i):
imagepath = self.cache_dir + i
if not os.path.exists(imagepath) or not wx.Image.CanRead(imagepath):
retval = False
else:
retval = False
return retval
Кроме того, я хотел бы добавить, что иногда, просто до аварии я получаю специфические ошибки в моей консоли, они выглядят как коррумпированные ошибки изображения, но изображения не повреждены, ошибка произошла на всех этапах на всех изображениях.
Application transferred too few scanlines [2009-09-08 11:12:03] Error: JPEG: Couldn't load - file is probably corrupted. [2009-09-08 11:12:11] Debug: ....\src\msw\dib.cpp(134): 'CreateDIBSection' fail ed with error 0x00000000 (the operation completed successfully.).
Эти ошибки могут произойти по-ла-карте или все вместе. Я думаю, что в какой-то момент память становится поврежденной и все, что происходит дальше, если я загружаю новую транзакцию или изображение или выполняю операцию обрезки - она требует погружения.
Так, к сожалению, после того, как попробовать предложение перемещения вызова функции предварительной загрузки в wxImage в основной графический интерфейс нить я все еще получаю ошибку - снова это произойдет после того, как слишком много изображений были загружены в память или если они сидят в памяти слишком долго. Затем, когда я пытаюсь обрезать изображение, я получаю ошибку памяти - что-то развращает, будь то в первом случае я слишком много использую или не имею достаточного количества (что не имеет смысла, потому что я увеличил размер файла подкачки до астрономических пропорций) или в последнем случае, когда длительность времени вызывает утечку или повреждение
Единственный способ, я думаю, что я могу пойти на этом этапе - использовать отладчик - есть ли какие-либо простые способы отладки приложения wxPython? Я хотел бы видеть, в частности, использование памяти.
Основная причина, по которой я думаю, что мне нужно предварительно загрузить изображения, потому что, если я вызываю wxImage на каждое изображение (я показываю два за раз) каждый раз, когда я загружаю «транзакцию», интерфейс от одной транзакции к следующей очень медленный и неуклюжий - если я загружу их в память очень быстро, но тогда я получаю ошибку в памяти.
Python делает сбор мусора, но если есть какие-либо ссылки, оставленные объекту, очевидно, что GC оставит его в покое. Так утечки памяти такого рода очень сильно зависят от того, как вы написали приложение. Одной небольшой ошибки в одной строке кода достаточно, чтобы сохранить ссылку и сохранить объект в живых. В целом, покажите нам код. –
Если вы все еще получаете ошибку, я бы разместил ее в списке рассылки wxpython (группа google: wxpython-users) и посмотрел, поможет ли Робин Данн или другой гуру. Сожалею! – DrBloodmoney
:) Хорошо. Хорошо, спасибо за предложение - он был твердый, но я должен делать что-то напуганное! – 2009-09-16 18:10:03