-
Notifications
You must be signed in to change notification settings - Fork 27
High memory use and possible leak with sequential access mode #268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi @mzur, This is the libvips operation cache -- it's tracking recent operations and trying to reuse them. If you disable the cache with
|
Thanks! So now I have this: <?php
include 'vendor/autoload.php';
use Jcupitt\Vips\Image;
use Jcupitt\Vips\Config;
$access = 'sequential';
// $access = 'random';
Config::cacheSetMax(0);
for ($i=0; $i < 10; $i++) {
$image = Image::newFromFile('my_image.jpg', ['access' => $access]);
$width = $image->width;
$height = $image->height;
$buf = $image->crop(round($width / 2) - 150, round($height / 2) - 150, 300, 300)
->writeToBuffer('.jpg');
} But it still uses lots of memory, increasing with the number of loop iterations:
|
|
I did some more experiments, re-encoded the image, converted it to PNG but nothing helped. Even if I found a way to reduce the amount of memory used, this would only delay the issue, as the used memory would still stack up (only slower). I found no way to clear the memory. It also seems to be outside of the |
Sorry, I was stuck on another issue. I'll have a look into this today. |
No need to apologize at all! I think there is nothing to be done about the continuously increasing memory usage. PHP just isn't designed for continuously running scripts. My first observation with |
Hi, I think I may be hitting the same issue, but with the thumbnail function.
I have this code in a loop and memory is increasing. Even tried |
Had to disable the use of vips on production since I tried everything but memory was increasing on each thumbnail generated... |
This is strange, I don't see this when running at the CLI. For example: #!/usr/bin/env php
<?php
require __DIR__ . '/vendor/autoload.php';
use Jcupitt\Vips;
if (count($argv) != 2) {
echo("usage: ./thumbnail-loop.php input\n");
exit(1);
}
function thumbnail($filename)
{
$image = Vips\Image::thumbnail($filename, 600, [
'height' => 10_000_000,
'export-profile' => 'srgb'
]);
$buf = $image->writeToBuffer('.jpg', [
'Q' => 75,
'strip' => TRUE,
'optimize_coding' => TRUE,
'profile'=>'srgb'
]);
return $buf;
}
echo "iteration, now (kb), growth (kb)\n";
$prev = 0;
for ($i = 0; $i < 100000; $i++) {
$buf = thumbnail($argv[1]);
if ($i % 10 == 0) {
gc_collect_cycles();
$pid = getmypid();
$now = intval(`ps --pid $pid --no-headers -orss`);
$use = $now - $prev;
$prev = $now;
echo "$i, $now, $use\n";
}
} With this sample JPEG:
I see:
You can see size stabilises at about 180mb after maybe 8000 iterations, so I would say that's classic memory fragmentation and no leaks. jemalloc makes it stabilise more quickly:
Now it's stable after only 100 iterations, and at a lower level. |
That's php 8.4.5 on ubuntu 25.04 with libvips 8.17, I should have said, though I think older versions behave the same. |
I tried with libvips 8.14 and it also seems fine:
I think I'd need some way to be able to reproduce this high memory use before I could investigate further. |
Hi again @mzur, I finally got around to this (sorry). I made this program, based on yours: #!/usr/bin/env php
<?php
require __DIR__ . '/vendor/autoload.php';
use Jcupitt\Vips;
$access = 'sequential';
// $access = 'random';
echo "iteration, now (kb), growth (kb)\n";
$prev = 0;
for ($i=0; $i < 100000; $i++) {
$image = Vips\Image::newFromFile($argv[1], ['access' => $access]);
$width = $image->width;
$height = $image->height;
$buf = $image
->crop(round($width / 2) - 150, round($height / 2) - 150, 300, 300)
->writeToBuffer('.jpg');
if ($i % 10 == 0) {
gc_collect_cycles();
$pid = getmypid();
$now = intval(`ps --pid $pid --no-headers -orss`);
$use = $now - $prev;
$prev = $now;
echo "$i, $now, $use\n";
}
} With a 6kx 4k sample JPEG I see:
It seems stable up to 3000 iterations at least. 600mb is a lot. This PC has 32 cores and this task has almost no parallelism, so you can shrink the libvips threadpool right down with no loss in speed:
Now it's down to 100mb. jemalloc would help a little more. |
Uh oh!
There was an error while loading. Please reload this page.
Hi, first of all thank you @jcupitt for this library and your incredible support!
I ran across an issue where
sequential
access mode seems to consume a lot more memory and also seems to have a leak where memory is not freed after processing, comapred torandom
mode. Here is a minimal example script:When I use
sequential
mode and call/usr/bin/time -v php my_script.php
I get:So it uses 15 GB to process the images. When I increase the number of iterations in the loop, the consumed memory also increases.
With
random
mode I get:It is faster and only uses 500 MB.
The image I use is a heavily compressed JPEG (~60 MB):
I can share the actual file via email but not publicly here.
I use vips-8.15.1 and jcupitt/vips:2.4.1.
The text was updated successfully, but these errors were encountered: