I am investigating a memory leak (or "bloat") in a Python (3.5.2) application using OpenCV (3.4.1, local build) on Ubuntu 16.04 (x86).
The application writes images to a file very often, and it uses .imwrite() method for this purpose. I have discovered that this usage of .imwrite() causes the RAM usage to grow wild, but I cannot find the reason for this behavior.
In order to debug this issue, I have prepared this simple test script:
#!/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)
While running this script, I monitored the free RAM (samples the free memory ever 10 seconds):
$ 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
The last sample, where the free memory returns to its initial value, was taken after I deleted the images files from target, which might suggest that this an OS issue, or maybe that the files aren't being closed properly by the program (Although I couldn't find a clue for this in the C++ source code).
I find this behavior very weird, even more so because imwrite is such a basic method. Can anyone give a hand in debugging and solving this issue?
Edit
So apparently the memory consumption in my test script is due to the fact that /tmp is actually a RAM drive, but the problem still stands when writing to an external drive which is connected through Ethernet adapter.
Update
The problem reproduces when writing to a local folder on a physical drive. It seems that this is a general OS problem not related specifically to imwrite. The OS caches the files, but doesn't ever free this cache (maybe it "thinks" it has enough memory for all this caching).
Executing 'echo 3 > /proc/sys/vm/drop_caches' periodically, as suggested here and here is a reasonable workaround for now, but we would like a less intrusive/violent solution, something that will prevent the system from using so much cache, or that will make it free the cache without force.
It looks like /tmp might be some kind of ramdisk mount, so it might consume RAM, instead of disk space, and is emptied after reboot.
https://wiki.archlinux.org/index.php/tmpfs
You can confirm it by testing your script for different destination folders, like directing the storage of the files into your home directory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With