Python 一旦我用PyInstaller打包了我的应用程序,内存错误就成了一个大问题。垃圾收集问题?还有别的吗?我被难住了 问题

Python 一旦我用PyInstaller打包了我的应用程序,内存错误就成了一个大问题。垃圾收集问题?还有别的吗?我被难住了 问题,python,pyinstaller,Python,Pyinstaller,总结的问题是,当我使用PyInstaller打包我的应用程序时,会出现左右抛出的MemoryError。我怀疑这与主队列对象没有被垃圾收集有关,但是,我对此一无所知。从源代码运行时,它运行100%正常,只占用几MB内存。只有一次包装后,气球才会失控 项目概述 我有一个GUI应用程序,它提供桌面的图像转换效果,并作为一个选项将屏幕记录保存到磁盘上 由于Python的线程不是真正并发的,所以程序的所有主要部分都在单独的多处理进程中运行,并通过共享队列对象进行通信 基本设置如下: 它是基本的生产者/消

总结的问题是,当我使用PyInstaller打包我的应用程序时,会出现左右抛出的MemoryError。我怀疑这与主队列对象没有被垃圾收集有关,但是,我对此一无所知。从源代码运行时,它运行100%正常,只占用几MB内存。只有一次包装后,气球才会失控

项目概述 我有一个GUI应用程序,它提供桌面的图像转换效果,并作为一个选项将屏幕记录保存到磁盘上

由于Python的线程不是真正并发的,所以程序的所有主要部分都在单独的多处理进程中运行,并通过共享队列对象进行通信

基本设置如下:

它是基本的生产者/消费者。ScreenMonitor生成屏幕的快照,这些快照被推送到队列中,以便ImageProcessor可以使用它们。程序的最大吞吐量点是队列对象。几乎所有与程序相关的东西都会在那里传输——而且以内存上升的速度,它必须在那里备份

作为另一个数据点,当从源代码直接运行时,程序运行正常。即使有多个进程和繁重的图像处理,它也只占用几MB的ram。此外,我还进行了长时间、4-5小时的压力测试,以检查是否存在明显的泄漏和非泄漏。所以,PyInstaller一定很有趣

源源不断 这就是程序在大范围运行时的内存占用,以尽可能快的速度处理

运行打包版本 那是在让它运行大约30秒之后。大约3-4分钟后,它会变成一个内存错误

一些代码 注意:下面有大量注释,我带了大量的程序簿记,所以如果下面看起来有问题,或者变量不匹配,那是因为大量的编辑。我想说的不是生产代码:

实际上,它的核心是一个非常基本的概念。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运行?到目前为止,我很困惑,我的应用程序或多或少都没有功能。有什么想法吗?

作为调试步骤,如果添加导入gc会发生什么;启动时是否启用gc.enable?这有帮助吗?您可以检查gc.isenabled或显式地告诉python使用gc进行清理。collect@gregb212刚刚测试过。不幸的是,行为没有改变。它仍然相对较快地从内存中溢出。您的代码中是否支持multiprocessing.freeze\u?您需要使用pyinstaller或类似的工具。