我正在使用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)
在运行此脚本时,我监控了空闲RAM(对空闲内存进行了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驱动器,但是当写入通过以太网适配器连接的外部驱动器时问题仍然存在。
更新
写入物理驱动器上的本地文件夹时,问题会重现。这似乎是一个与imwrite无关的一般操作系统问题。操作系统缓存文件,但不会释放此缓存(也许它“认为”它有足够的内存用于所有这些缓存)。
按照建议的here和here定期执行'echo 3 > /proc/sys/vm/drop_caches'
目前是一个合理的解决方法,但我们想要一个不那么干扰/暴力的解决方案,这会阻止系统使用这么多缓存,或者这将使它在没有武力的情况下释放缓存。
答案 0 :(得分:2)
看起来/ tmp可能是某种ramdisk挂载,因此它可能会消耗RAM而不是磁盘空间,并在重新启动后清空。
https://wiki.archlinux.org/index.php/tmpfs
您可以通过测试不同目标文件夹的脚本来确认它,例如将文件存储到您的主目录中。