vips 和 pyvips 物理内存使用
vips and pyvips physical memory usage
我循环读取了 100 张 jpeg 图片并从中提取了不同的区域。
循环内容:
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;
或 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())
我看RSS,物理内存使用情况。它从大约 40MB 开始,然后随着每个图像的增长而增长。
这是一张图表:
这是原始尺寸为 4 倍且裁剪原点相同的图像的图表,width/height。
为什么会这样?某处有泄漏吗?
当我设置一个标记来跟踪泄漏时,pyvips.base.leak_set(1)
,我得到了大约 60 MB 的报告。我还使用 cgroups 将进程的物理内存限制为 100 MB。 Vips 能够 运行,而不会崩溃,但速度较慢。
相比之下,OpenCV 中的类似操作消耗的 RSS 量几乎是恒定的,140 MB 或 300 MB,具体取决于图像大小。对于我的实验,vips 在 CPU 时间内赢了几次,但在内存中输了几次。
pyvips版本:2.0.4
libvips 版本:8.6.1
我试过这个测试程序:
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()
我运行是这样的:
$ mkdir samples
$ for i in {1..2000}; do cp ~/pics/k2.jpg samples/$i.jpg; done
$ python soak.py samples/*
k2.jpg
是一张 2k x 1.5k RGB jpg 图像。在 运行 期间,我在 top
中观看了 RES。它在开始时略有上升,但在 100 张左右的图像稳定在 75MB 左右并在剩余的 1900 次迭代中保持不变。这是 py27, pyvips 2.0.4, libvips 8.6.1.
libvips 保持 cache of recent operations。通常这是无害的(并且有帮助),但在某些情况下它会触发不需要的内存使用。
您可以尝试添加:
pyvips.cache_set_max(0)
接近程序开始。对于此示例,它将峰值内存从 75mb 降低到 38mb。
我循环读取了 100 张 jpeg 图片并从中提取了不同的区域。
循环内容:
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;
或 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())
我看RSS,物理内存使用情况。它从大约 40MB 开始,然后随着每个图像的增长而增长。
这是一张图表:
这是原始尺寸为 4 倍且裁剪原点相同的图像的图表,width/height。
为什么会这样?某处有泄漏吗?
当我设置一个标记来跟踪泄漏时,pyvips.base.leak_set(1)
,我得到了大约 60 MB 的报告。我还使用 cgroups 将进程的物理内存限制为 100 MB。 Vips 能够 运行,而不会崩溃,但速度较慢。
相比之下,OpenCV 中的类似操作消耗的 RSS 量几乎是恒定的,140 MB 或 300 MB,具体取决于图像大小。对于我的实验,vips 在 CPU 时间内赢了几次,但在内存中输了几次。
pyvips版本:2.0.4
libvips 版本:8.6.1
我试过这个测试程序:
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()
我运行是这样的:
$ mkdir samples
$ for i in {1..2000}; do cp ~/pics/k2.jpg samples/$i.jpg; done
$ python soak.py samples/*
k2.jpg
是一张 2k x 1.5k RGB jpg 图像。在 运行 期间,我在 top
中观看了 RES。它在开始时略有上升,但在 100 张左右的图像稳定在 75MB 左右并在剩余的 1900 次迭代中保持不变。这是 py27, pyvips 2.0.4, libvips 8.6.1.
libvips 保持 cache of recent operations。通常这是无害的(并且有帮助),但在某些情况下它会触发不需要的内存使用。
您可以尝试添加:
pyvips.cache_set_max(0)
接近程序开始。对于此示例,它将峰值内存从 75mb 降低到 38mb。