【问题标题】:Python raspberry Pi timelapse memory leak?Python树莓派游戏中时光倒流内存泄漏?
【发布时间】:2018-05-23 20:51:51
【问题描述】:

我正在使用我的树莓派 Pi3 来制作延时摄影视频。我有一个每分钟运行一个 python 脚本的 cron,它决定要拍摄多少张照片,然后从另一个拍摄实际照片的 python 脚本中导入一个函数。问题是,在运行大约 4 小时后,相机停止拍照——如果我尝试手动拍照,它会说内存不足,top 确认了这一点。如果我在游戏中时光倒流运行时观看top,内存使用量会稳步攀升。

我认为我已将问题缩小到拍摄照片的 python 脚本。我可以自己运行它,如果我启动 pi 并运行它几次,我会看到第一次运行使用的内存增加了约 10MB,随后每次运行增加了约 1MB(帖子底部的屏幕截图)。这是脚本

import time
import picamera
import os

def ShutterTS(dirname):
    with picamera.PiCamera() as cam:
        cam.resolution=(1920,1440)
        cam.rotation=180
        cam.hflip=True
        # camera warm up time
        time.sleep(2)  
        FNfmt = "%4d%02d%02d_%02d:%02d:%02d.JPG"
        Fname = FNfmt % time.localtime()[0:6]
        framename = os.path.join(dirname, Fname)
        cam.capture(framename)
        return

def main():
    dirname = [insert path here, my path hidden]
    ShutterTS(dirname)
    return

if __name__ == '__main__':
    import sys
    sys.exit(main())

我不是一个好的编码员,我基本上是从互联网上找到的一些东西拼凑起来的,所以我希望这是我错过的非常简单的东西。 with 是树莓派推荐的调用相机的方式。我知道这应该在退出时关闭相机实例,但我猜有些东西在内存中徘徊?我尝试在函数末尾添加close.cam(),但没有任何区别(没想到会这样)。我已经在函数末尾的所有变量上尝试了del,但没有任何区别。我认为函数末尾的return 是多余的,但添加它没有任何区别。

这个网站https://www.linuxatemyram.com/ 建议top 显示内存攀升是正常的,free -m 是一个更好的指标,这表明有足够的可用空间——但事实仍然是相机停止工作,说内存不足。任何线索将不胜感激!

这是 cron 脚本(裁剪了其他一些导入)

from ShutterTimestamp import ShutterTS
from makedirectory import testmakedir
from SunTimesA import gettimes

def Timer(dirname,FRAMES_PER_MINUTE):
    # I take a picture first and then loop so the program isn't
    # sleeping pointlessly to the end of the minute
    start = time.time()
    ShutterTS(dirname)
    if FRAMES_PER_MINUTE>1:
        for frame in range(FRAMES_PER_MINUTE-1):
            time.sleep(int(60 / FRAMES_PER_MINUTE) - (time.time() - start))
            start = time.time()
            ShutterTS(dirname)
    return

def main():
    dirfmt = []
    dirname = dirfmt % time.localtime()[0:3]
    FPM=gettimes()
    if FPM > 0:
        testmakedir(dirname)
        Timer(dirname,FPM)
    return

if __name__ == '__main__':
    sys.exit(main())

Screenshot of memory use

【问题讨论】:

  • “我有一个 cron,它每分钟运行一个 python 脚本来决定要拍摄多少张照片,然后从另一个拍摄实际照片的 python 脚本中导入一个函数。”向我们展示导入脚本。您向我们展示的内容不应导致内存泄漏。
  • 感谢 Dave,我已将 cron 脚本添加到我的原始帖子中,但请注意,当作为独立程序运行拍摄单张照片时,第一个脚本似乎会导致内存泄漏。
  • 独立脚本在退出时会释放内存,除非发生了异常情况。 gettimes() 是否在做一些使用非常量内存的事情?
  • gettimes() 使用 Astral 模块 (astral.readthedocs.io/en/stable/index.html) 来判断太阳是否升起以及是否拍照。我在帖子末尾添加了内存问题的屏幕截图。 “SunTimesA.py”是包含gettimes() 函数的python 脚本。您可以看到运行此内存使用后略有增加,但随着内存被释放,这会卷回。 “ShutterTimestamp.py”是包含ShutterTS() 函数的python 脚本。多次运行后,内存使用量显着增加,并且不会随着时间的推移而回落。
  • 更新以防有人阅读此问题。我从来没有为这个问题找到满意的答案。但是,当我格式化存储卡并安装新版本的操作系统时,我“解决了”它。一旦它全部启动并再次运行,内存泄漏问题就不存在了。

标签: python memory memory-leaks raspberry-pi


【解决方案1】:

我想你有一个包装 python 脚本,它导入你在问题中提供的脚本并在循环中调用ShutterTS。此函数不会向主脚本返回任何输出(只是return)。

如果您可以观察到内存泄漏,它可能位于 picamera 模块中。 一种解决方法是将此脚本作为子进程调用,而不是作为主进程中的函数调用。可以在 shell 脚本或使用subprocess 模块的 python 脚本中完成。

因此每次捕获后都会释放内存。

【讨论】:

    猜你喜欢
    • 2018-03-17
    • 2016-05-10
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    相关资源
    最近更新 更多