一旦我用PyInstaller打包我的应用程序,MemoryErrors就会出现巨大的问题。垃圾收集问题?别的什么?我很难过

时间:2013-09-26 19:34:44

标签: python pyinstaller

问题

总结的问题是,当我使用PyInstaller打包我的应用程序时,我正在左右抛出MemoryErrors。我怀疑它与主要queue对象没有被垃圾收集有关,但是,我在这里很黑暗。它从源运行时运行100%正常,只占用几MB内存。只有一次打包,它就会失控。

计划概览

我有GUI应用程序,它提供桌面的图像转换(基本上是愚蠢的效果),并且(作为选项)将屏幕的记录保存到磁盘。

由于Python的线程不是真正并发的,程序的所有主要部分都在一个单独的multiprocessing进程中运行,并通过共享的Queue对象进行通信。

基本设置如下:

enter image description here

它是基本的生产者/消费者。 ScreenMonitor生成屏幕的快照,这些快照被推入队列,以便ImageProcessor可以使用它们。程序的大吞吐点是queue对象。只是与程序相关的所有都会在那里传输 - 并且按照内存爬升的速度,它必须在那里备份。

作为另一个数据点,程序在从源代码运行时运行A-OK。即使有多个进程和繁重的图像处理,它只占用几MB的RAM。另外,我进行了长达4-5小时的压力测试,以检查是否有泄漏,非显而易见。所以,PyInstaller必须要有趣。

从源

运行

enter image description here

这是程序内存占用,同时运行全开,尽可能快地处理。

正在运行打包版本

enter image description here

这是让它运行约30秒后。大约3-4分钟后它会转入内存错误。

一些代码

注意:下面有大量注释,我拿出了大量的程序簿,所以如果下面看起来有问题,或者变量不匹配,那是因为编辑过量。这是不是生产代码就是我所说的:)

真的,在它的核心,它是一个非常基本的producer/consumer pattern Process2将图片数据放入队列,Process2对图片进行操作。

class Grabber(NoDaemonProcess):
    def __init__(self, in_queue, msg_queue):
        multiprocessing.Process.__init__(self)
        self.queue = in_queue
        self.ext_msg_queue = msg_queue
        self.settings = Settings()
        self.count = 0
        self.name == multiprocessing.current_process().name
        self.running = True

    def run(self):
        start_time = time.time()
        current = self.grab()

        img_queue = multiprocessing.Queue()
        image_processor = ImageProcess(img_queue, self.save_path)
        image_processor.start()

        clock = Clock()
        time.clock()
        while self.running:
            buffer_type, content, times = self.get(current, img_queue)
            self.img_queue.put((buffer_type, content, times))


class ImageProcess(NoDaemonProcess):
    def __init__(self, queue, save_path):
        multiprocessing.Process.__init__(self)
        self.in_queue = queue 
        self.save_path = save_path
        self.running = True
        # self.daemon = False

    def run(self):
        out_queue = Queue.Queue()
        threads = []
        for i in range(5):
            t = ImageSaver(out_queue)
            t.setDaemon(True)
            t.start()
            threads.append(t)
        # classmethod; effects all instances
        ImageSaver.setSavePath(self.save_path)

        while self.running: 
            queue_item = self.in_queue.get()
            buffer_type, content, times = queue_item
            # Do stuff with image stream.. 

原来如此!有谁之前经历过这个吗? PyInstaller中有什么东西阻止GC运行吗?截至目前,我很难过,我的应用程序或多或少都没有功能。有任何想法吗?

0 个答案:

没有答案