PHP Imagick 메모리 누수




memory-leaks (3)

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 메모리 및 가비지 수집을 조정해도 도움이되지 않습니다.

나는 동일한 문제를 가지고 있었고, 3000x2000 픽셀의 50 (!) 페이지를 가진 다중 페이지 -TIFF 이미지를 처리하려고 시도했다. 해결책은 이미지 캐시를 디스크에 저장하는 것입니다.

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 대신 디스크에 저장하는 것입니다. 기본 위치는 files / tmp / magick-XXnnnnn 인 것처럼 보이므로 / tmp가 shmfs / ramdisk에 없거나 imagick이 사용하는 임시 디렉토리를 변경하십시오.

조사 할 다른 자원 한계 : imagick::RESOURCETYPE_DISK , imagick::RESOURCETYPE_FILEimagick::RESOURCETYPE_AREA . 그것들은 imagick :: getResourceLimit () 매뉴얼 페이지에 설명되어 있습니다 ( setResourceLimit() 페이지에는 그리 좋지 않습니다).

내 이미지 처리 루프에서는 set_time_limit(300) 을 사용했습니다. 스크립트에서이 거대한 (압축을 풀 때) 이미지를 처리하기 위해 나이가 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);

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 one보다 부드럽게 작동합니다. 하지만 오류가 발생하기 쉬운 코드를 좋아하지 않습니다.


나는 이것이 오래되었다는 것을 알고 있지만 같은 문제가 발생하여 $im->destroy() 대신 $im->clear() 를 호출하면 메모리 누수가 수정되었다.

Imagick::destroy() has been deprecated in favor of Imagick::clear() 문서 Imagick::destroy() has been deprecated in favor of Imagick::clear() . 따라서 clear() 사용해야합니다.





imagick