【发布时间】:2015-11-02 01:28:05
【问题描述】:
我有一个使用Picamera 库的运动检测脚本。我使用PicameraCircularIO 流对象,它继承自CircularIO 类(仍然是Picamera 库的一个类),它继承自本机Python BytesIO 类。
问题是当录制到循环流中,然后将流的内容写入磁盘时,内存没有被清除。
将流写入磁盘后,我会这样做:
stream.seek(0)
stream.truncate()
我也尝试过调用stream.flush() 和/或关闭流:stream.close(),但没有帮助。
我还尝试删除对流的所有引用以对其进行垃圾收集(即使这样做没有意义,因为将流截断为大小 0 通常应该可以完成这项工作......)。流在一个数组中,所以我做了del streams[index]。不行,我也尝试手动调用垃圾回收器:gc.collect(),没有效果。
内存中只计算流中写入的字节数,而不是流大小。所以举个例子,如果将 2125000 字节写入流中,然后我将其截断,那么内存中仍然会有 2125000 字节。
感谢任何提示/技巧/答案。
干杯!
【问题讨论】:
-
我不知道这个 picamera 库。你如何测量你的内存大小(即你怎么知道你没有释放内存)?问题是您的进程仍在使用内存吗?如果是这样,请参阅stackoverflow.com/questions/15455048/releasing-memory-in-python 您可以生成一个子进程来读取流并在完成后让子进程退出,这将释放内存。
-
我在执行脚本时使用
top命令监控内存。您发布的链接可能有用,我会尽快查看! -
是的,我相信,'gc.collect' 会在进程中将内存标记为可重用,但不一定会放手。您的进程可能会将其大小保持在内存使用的“高水位线”。因此,启动子进程并在完成后退出的想法。操作系统总是以这种方式收回内存。
-
读得非常好!如果我理解正确,
top命令中显示的内存百分比不一定是正在使用的内存,而是脚本保留的内存(也就是水印)。那么如果内存实际上是空闲的,我就没有问题了。这就解释了为什么当我清空一个流并开始填充另一个流时,内存百分比不会上升,因为它必须越过水位线才能增加百分比。 -
是的,如果你开始填充另一个流,你的进程不应该增长,它应该开始重用它已经分配的相同空间。除非您遇到某种内部内存碎片或其他类型的内存泄漏,否则应该没问题。
标签: python memory-management stream garbage-collection video-streaming