【问题标题】:How to remove a stream from memory?如何从内存中删除流?
【发布时间】: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


【解决方案1】:

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

在您的情况下,这应该没问题,因为您正在释放流。如果您开始使用另一个流,它应该重复使用相同的空间,并且您的“顶部”报告不应显示大小增加。

请参阅Releasing memory in Python 了解更详细的说明。

【讨论】:

  • 但是我不需要手动调用gc.collect,因为垃圾收集器会自动完成它的工作,对吧?
  • 通常。我不会打扰。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
相关资源
最近更新 更多