I read 100 jpeg images in a loop and extract different areas from them.
Loop contents:
VImage in = VImage::new_from_file(impath.c_str(),
VImage::option()->
set( "access", VIPS_ACCESS_SEQUENTIAL ) );
VImage out = in.extract_area(x0, y0, x1 - x0, y1 - y0);
cout << out.avg() << endl;
Or the same thing in python:
img_full = pyvips.Image.new_from_file(impath, access='sequential')
img = img_full.extract_area(x0, y0, x1 - x0, y1 - y0)
print(img.avg())
I watch RSS, physical memory usage. It starts from around 40MB and then with each image it grows.
Here is the graph for images 4X the original size with the same crop's origin, width/height.
Why does it happen ? Is there a leak going somewhere ?
When I set a flag to trace leaks, pyvips.base.leak_set(1)
, I get about 60 MB reported. Also I used cgroups to limit a physical memory for a process to 100 MB. Vips is able to run, without crashing, but is slower.
For comparison, the similar operations in OpenCV consume almost a constant amount of RSS, 140 MB or 300 MB depending on the image size. For my experiments, vips wins several times in CPU time, but looses several times in memory.
pyvips version: 2.0.4
libvips version: 8.6.1
I tried this test program:
import sys
import pyvips
import random
for filename in sys.argv[1:]:
image = pyvips.Image.new_from_file(filename, access='sequential')
x = random.randint(0, image.width - 2)
y = random.randint(0, image.height - 2)
w = random.randint(1, image.width - x)
h = random.randint(1, image.height - y)
print 'filename =', filename, 'avg =', image.crop(x, y, w, h).avg()
I ran it like this:
$ mkdir samples
$ for i in {1..2000}; do cp ~/pics/k2.jpg samples/$i.jpg; done
$ python soak.py samples/*
k2.jpg
is a 2k x 1.5k RGB jpg image. While it ran, I watched RES in top
. It rose a little at the start, but after 100 or so images stabilized at around 75MB and stayed there for the remaining 1900 iterations. This is with py27, pyvips 2.0.4, libvips 8.6.1.
libvips keeps a cache of recent operations. Usually this is harmless (and helpful), but it can trigger unwanted memory use in some cases.
You could try adding:
pyvips.cache_set_max(0)
Near the start of your program. For this example, it dropped peak memuse down from 75mb to 38mb.