我正在研究在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'
(目前建议使用here和here是一种合理的解决方法),但是我们希望使用一种不那么侵入性/暴力性的解决方案,该解决方案将阻止系统使用过多的缓存,或者使系统无需费力就释放缓存。 最佳答案
看起来/tmp可能是某种ramdisk挂载,因此它可能会消耗RAM而不是磁盘空间,并且在重新启动后将其清空。
https://wiki.archlinux.org/index.php/tmpfs
您可以通过针对不同的目标文件夹测试脚本来确认这一点,例如将文件存储定向到主目录中。