2012-04-03 21 views
6

मुझे PHP सीएलआई पर इमेगिक के साथ कुछ प्रस्तुत करना होगा। मैंने देखा है कि प्रत्येक 3-5 दिन सर्वर मेमोरी भर जाती है, इसलिए मैं ssh या ftp के माध्यम से भी connet नहीं कर सकता।PHP इमेजिक मेमोरी लीक

memory_get_usage() के साथ मैंने स्क्रिप्ट के कल्पना भाग में स्मृति रिसाव को कम किया। स्क्रिप्ट इस तरह दिखता है:

$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() विधि सबसे अधिक स्मृति लेता है

क्या मैं छवि द्वारा उपयोग की गई जगह को खाली करने के लिए कुछ और कर सकता हूं?

image of the memory consumption

उत्तर

15

इमेज एक साझा लाइब्रेरी का उपयोग करता है और इसका मेमोरी उपयोग PHP के लिए पहुंच से बाहर है, इसलिए PHP मेमोरी और कचरा संग्रह ट्यूनिंग मदद नहीं करेगा।

मुझे 3000x2000 पिक्सेल के 50 (!) पृष्ठों के साथ एक बहु पृष्ठ-टिफ छवि को संभालने का प्रयास करने में स्वयं एक ही समस्या थी। समाधान यह है कि कल्पना पर डिस्क पर पिक्सेल कैश डालें।

जोड़ना 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 डिस्क पर बजाय रैम में अपनी पिक्सेल कैश डाल बनाने के लिए है। डिफ़ॉल्ट स्थान फ़ाइलें/tmp/magick-XXnnnnn प्रतीत होता है, इसलिए सुनिश्चित करें कि shmfs/ramdisk पर/tmp नहीं है, या temp निर्देशिका इमेक्टिक उपयोगों को बदलें।

जांच के लिए अन्य resouce सीमा: imagick::RESOURCETYPE_DISK, imagick::RESOURCETYPE_FILE, और imagick::RESOURCETYPE_AREA। उन्हें imagick::getResourceLimit() manual page में वर्णित किया गया है (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); 
+0

मैंने पहले से ही इस समस्या को छोड़ दिया है। लेकिन यह समाधान बहुत अच्छा काम करता है। धन्यवाद – Slemgrim

+0

कोई भी जावा में कुछ भी जानता है? – krakover

+0

तो यह डिस्क को रैम के बजाय भर देगा? यह कैश क्या है? –

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 एक काम करता है। लेकिन मुझे त्रुटि-प्रवण कोड पसंद नहीं है।

+0

हम्म अच्छी तरह से यह निश्चित रूप से काम करता है, लेकिन php के भीतर से खोल आदेशों को कॉल करने की बदसूरतता से अलग, कुछ उत्पादन सर्वर निष्पादन पर सुरक्षा कारणों से वास्तव में अक्षम किया जाता है। – Toumal

3

मैं जानता हूँ कि इस पुरानी है, लेकिन मैं में भाग $im->destroy() के बजाय एक ही समस्या और $im->clear() को कॉल करना मेरे लिए मेमोरी रिसाव तय करता है।

documentationImagick::destroy() has been deprecated in favor of Imagick::clear() के अनुसार। तो clear() का उपयोग किया जाना चाहिए।

संबंधित मुद्दे