我正在研究在Ubuntu 16.04(x86)上使用OpenCV(3.4.1,本地版本)的Python(3.5.2)应用程序中的内存泄漏(或“膨胀”)。

该应用程序经常将图像写入文件,并且为此目的使用 .imwrite() 方法。我发现.imwrite()的这种用法会导致RAM的使用激增,但我找不到这种现象的原因。

为了调试此问题,我准备了以下简单的测试脚本:

#!/usr/bin/python3

import cv2
import time

img = cv2.imread("vista.jpg")

idx = 0
while True:
    filename = "/tmp/vista_copy_" + str(idx) + ".tiff"
    cv2.imwrite(filename, img)
    idx = idx + 1
    time.sleep(1)

运行此脚本时,我监视了可用内存(每10秒对可用内存进行一次采样):
$ while [ 1 ] ; do grep MemFree /proc/meminfo ; sleep 10 ; done
MemFree:          898024 kB
MemFree:          780640 kB
MemFree:          667848 kB
MemFree:          545700 kB
MemFree:          437196 kB
MemFree:          315820 kB
MemFree:          298380 kB
MemFree:          298292 kB
MemFree:          297448 kB
MemFree:          297080 kB
MemFree:          915616 kB

最后一个示例是在我从目标删除镜像文件之后,获取了可用内存返回其初始值的信息,这可能表明这是操作系统问题,或者可能是程序未正确关闭文件(尽管我在C++源代码中找不到此线索。
我发现这种行为很奇怪,甚至更是如此,因为imwrite是一种基本的方法。谁能帮助调试和解决此问题?

编辑
因此,显然,我的测试脚本中的内存消耗是由于/tmp实际上是RAM驱动器,但是在写入通过以太网适配器连接的外部驱动器时,问题仍然存在。

更新
当写入物理驱动器上的本地文件夹时,问题再次出现。看来这是一个普遍的操作系统问题,与笔迹无关。操作系统会缓存文件,但永远不会释放该缓存(也许它“认为”它有足够的内存来进行所有这些缓存)。
暂时执行'echo 3 > /proc/sys/vm/drop_caches'(目前建议使用herehere是一种合理的解决方法),但是我们希望使用一种不那么侵入性/暴力性的解决方案,该解决方案将阻止系统使用过多的缓存,或者使系统无需费力就释放缓存。

最佳答案

看起来/tmp可能是某种ramdisk挂载,因此它可能会消耗RAM而不是磁盘空间,并且在重新启动后将其清空。

https://wiki.archlinux.org/index.php/tmpfs

您可以通过针对不同的目标文件夹测试脚本来确认这一点,例如将文件存储定向到主目录中。

10-04 13:38