[英]PHP Imagick memory leak
我必須在 PHP CLI 上用 Imagick 渲染一些東西。 我注意到每 3-5 天服務器內存就會變滿,所以我什至無法通過 ssh 或 ftp 連接。
使用 memory_get_usage() 我將內存泄漏縮小到腳本的 imagick 部分。 腳本看起來像這樣:
$sourceImg = 'source.png';
$destImg = 'dest.png';
$background ='#00ff00';
$im = new Imagick();
$im->pingImage($sourceImg);
$im->readImage($sourceImg);
$draw = new ImagickDraw();
for($i=1;$i<=5;$i++){
$draw->setFillColor( $background);
$draw->rectangle( 10*$i+5, 10, 10*$i+10, 20);
}
$im->drawImage( $draw );
$im->writeImage( $destImg );
$im->destroy();
unset($im,$draw);
我銷毀圖像引用,並取消設置 imagick 和 imagickDraw 對象,但腳本不會釋放任何內存。 setFillColor() 方法占用的內存最多
我可以做其他事情來釋放 imageick 使用的空間嗎?
imagick 使用共享庫,它的內存使用量對於 PHP 來說是遙不可及的,因此調整 PHP 內存和垃圾收集無濟於事。
我自己也遇到了同樣的問題,試圖處理 50 (!) 頁 3000x2000 像素的多頁 tiff 圖像。 解決方案是讓 imagick 將其像素緩存放在磁盤上。
在創建Imagick
對象之前添加它為我解決了這個問題:
// pixel cache max size
IMagick::setResourceLimit(imagick::RESOURCETYPE_MEMORY, 256);
// maximum amount of memory map to allocate for the pixel cache
IMagick::setResourceLimit(imagick::RESOURCETYPE_MAP, 256);
目標是讓 imagick 將其像素緩存放在磁盤而不是 RAM 中。 默認位置似乎是文件 /tmp/magick-XXnnnnn,因此請確保 /tmp 不在 shmfs/ramdisk 上,或者更改 imagick 使用的臨時目錄。
要調查的其他資源限制: imagick::RESOURCETYPE_DISK
、 imagick::RESOURCETYPE_FILE
和imagick::RESOURCETYPE_AREA
。 它們在imagick::getResourceLimit() 手冊頁中有描述(在setResourceLimit()
的頁面中不太好)。
在我的圖像處理循環中,我有set_time_limit(300)
,因為腳本需要很長時間來處理這個巨大的(解壓縮時)圖像。
setResourceLimit()
不應作為靜態方法調用,而應在實際對象上調用,例如:
$im->setResourceLimit(imagick::RESOURCETYPE_MEMORY, 256);
$im->setResourceLimit(imagick::RESOURCETYPE_MAP, 256);
$im->setResourceLimit(imagick::RESOURCETYPE_AREA, 1512);
$im->setResourceLimit(imagick::RESOURCETYPE_FILE, 768);
$im->setResourceLimit(imagick::RESOURCETYPE_DISK, -1);
我知道這是舊的,但我遇到了同樣的問題,調用$im->clear()
而不是$im->destroy()
為我修復了內存泄漏。
根據文檔Imagick::destroy() has been deprecated in favor of Imagick::clear()
。 所以應該使用clear()
。
你可以用這個。
請注意,根據釋放內存使用的文檔, clear()
優於destroy()
。
// clear temp files
$imagick_image->clear(); // in your case "$img->clear();"
您還可以運行 cron 為您刪除臨時文件,否則您的服務器可能會崩潰。 這不是php代碼,它是命令行代碼。
# linux command
find /tmp/ -name "magick-*" -type f -delete
# cron
45 * * * * find /tmp/ -name "magick-*" -type f -delete
xdebug 無法幫助我.. 所以我決定尋找另一種解決方案。 我想出了直接使用圖像魔法:
$sourceImg = 'source.png';
$destImg = 'dest.png';
$background ='#00ff00';
$command = "convert {$sourceImg}";
$out = array();
for($i=1;$i<=5;$i++){
$command .= " -fill \"{$background}\" ";
$command .= " -draw 'rectangle {$x1},{$y1} {$x2},{$y2}'";
}
$command .= " {$destImg}";
exec($command,$out);
這種解決方案的工作方式比 imagick 更順暢。 但我不喜歡容易出錯的代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.