我有一个运行Ubuntu 22.04的服务器,我安装了apache和php。我最近开始为php使用libvips,我注意到每次php脚本运行时,所使用的内存量越来越多。例如,如果空闲ram是15000 MB,在运行脚本几十次(不是同时)之后,空闲ram下降到5000 MB,没有被释放。
php文件示例:
<?php
require __DIR__ . '/vendor/autoload.php';
use JcupittVips;
$image = VipsImage::newFromFile($inputImagePath);
$image = $image->thumbnail_image($width, ['height' => $height, 'crop' => 'centre']);
$image->writeToFile($outputImagePath, ['Q' => $quality]);
相反,如果在文件末尾调用函数VipsConfig::shutDown();
,内存将被释放。
有时libvips也会返回一个错误:
(process:211949): GLib-GObject-WARNING **: 16:54:47.542: cannot register existing type 'VipsObject'
(process:211949): GLib-CRITICAL **: 16:54:47.542: g_once_init_leave: assertion 'result != 0' failed
(process:211949): GLib-GObject-CRITICAL **: 16:54:47.542: g_type_register_static: assertion 'parent_
type > 0' failed
(process:211949): GLib-CRITICAL **: 16:54:47.542: g_once_init_leave: assertion 'result != 0' failed
libvips42版本:8.12.1,php-vips版本:2.0.3
VipsConfig::shutDown()
释放各种libvips缓存,如果可以的话,我会叫它。另一种方法是为每个请求使用fork(),并依赖于操作系统进行清理(如果我理解你在做什么的话)。
不要使用thumbnail_image
,除非你必须,它只是在那里的情况下,你必须做一些处理之前缩略图。对于许多图像格式,简单地执行:
$image = VipsImage::thumbnail($inputImagePath, $width, [
'height' => $height,
'crop' => 'centre'
]);
由于thumbnail
在一次操作中结合了加载和调整大小,因此可以利用libjpeg shrink-on-load等技巧。
如果你使用:
$image = VipsImage::newFromFile($inputImagePath);
libvips将(可能,这取决于图像格式和大小)将图像解压缩到内存中,并将其保存在缓存中,以备再次使用。
您可以使用例如:
来减小缓存大小。VipsConfig::cacheSetMax(5);
现在libvips将只缓存前5个操作。
如果你使用顺序模式打开,你可以避免完全解压缩到内存。文档中有一章是关于libvips打开文件的各种方式以及这些方式如何影响内存使用的:
https://www.libvips.org/API/current/How-it-opens-files.html
Libvips 8.13解决了这个问题,但是在ubuntu 22.04上apt存储库包含8.12,所以你必须从源代码编译。
sudo apt-get remove libvips42
sudo add-apt-repository ppa:lovell/cgif
sudo apt-get update
sudo apt-get install libcgif-dev
sudo apt install
build-essential
ninja-build
python3-pip
bc
wget
pip3 install meson
sudo pip3 install meson
sudo apt install
libfftw3-dev
libopenexr-dev
libgsf-1-dev
libglib2.0-dev
liborc-dev
libopenslide-dev
libmatio-dev
libwebp-dev
libjpeg-turbo8-dev
libexpat1-dev
libexif-dev
libtiff5-dev
libcfitsio-dev
libpoppler-glib-dev
librsvg2-dev
libpango1.0-dev
libopenjp2-7-dev
libimagequant-dev
wget https://github.com/libvips/libvips/releases/download/v8.13.3/vips-8.13.3.tar.gz
tar xf vips-8.13.3.tar.gz
cd vips-8.13.3
meson build --libdir=lib --buildtype=release -Dintrospection=false
cd build
meson compile
meson test
sudo meson install
之后,您必须确保PHP FFI可以找到自定义构建。有很多方法可以做到这一点,一个简单的方法是设置VIPSHOME环境变量。
<?php
putenv('VIPSHOME=/usr/local');
libvips 8.13解决了这些问题。
见:https://github.com/libvips/php-vips/issues/149
您可以尝试调用
VipsConfig::concurrencySet(1);
在执行任何处理之前。它解决了我的应用程序中的问题,php在cli模式下运行。