1

我有一个使用Picamera库的动作检测脚本。我使用PicameraCircularIO流对象,该对象继承自CircularIO类(仍然是类的形式,即Picamera库),它继承自本机Python BytesIO类。如何从内存中删除流?

问题是,当记录到循环流中,然后在磁盘上写入流的内容时,内存不会被清除。

流已被写入磁盘上后,这是我做的:

stream.seek(0) 
stream.truncate() 

我也打过电话stream.flush()和/或关闭流:stream.close(),但它并没有帮助。

我也尝试删除所有对流的引用,以便它被垃圾回收(即使这样做没有意义,因为将流截断为0大小通常应该可以完成这项工作...)。该流是在一个数组中,所以我做了del streams[index]。它没有工作,所以我也尝试手动调用垃圾收集器:gc.collect(),没有任何效果。

它只是在流中正在被写入内存中的字节,而不是流的大小。例如,如果将2125000字节写入流中,然后将其截断,则内存中仍有2125000字节。

任何提示/技巧/答案赞赏。

干杯!

+1

我不知道这个picamera库。你如何衡量你的内存大小(即你如何知道自己没有释放内存)?问题是您的流程仍在使用内存?如果是这样,请参阅http://stackoverflow.com/questions/15455048/releasing-memory-in-python您可以产生一个子进程来读取流,并在完成后让子进程退出,这将释放内存。 – RobertB

+0

我正在执行脚本时用'top'命令监视内存。您发布的链接可能很有用,我很快就会看到! – maximedupre

+1

是的,我相信'gc.collect'会将内存标记为在进程内可重用,但不一定会放弃它。您的过程可能会将其大小保持在内存使用的“高水位”。因此,启动一个子进程并在完成时退出。操作系统将总是以这种方式收回内存。 – RobertB

回答

1

gc.collect将内存标记为未使用。由于您的程序需要更多的内存,它应该重用该内存。但是,它可能不会将该内存释放回操作系统,因此操作系统将继续报告所使用的内存。一般来说,python进程倾向于保留它们的内存并且不会释放它,因此它们的内存总占用空间将代表内存使用率的“高水位”。

就你而言,这应该是因为你释放流。如果您开始使用其他流,则应重复使用相同的空间,并且您的“顶级”报告不应显示大小的增加。

有关更详细的解释,请参阅Releasing memory in Python

+0

但我不需要手动调用'gc.collect',因为垃圾收集器会自动完成它的工作,对吧? – maximedupre

+0

通常。我不会打扰。 – RobertB