2010-06-24 14 views
13

मेरे पास एक PHP स्क्रिप्ट है जो क्रॉन पर चलती है जो निष्पादित करने में 15 मिनट तक लग सकती है। नियमित अंतराल पर मैंने इसे mem_get_usage() को थका दिया है, इसलिए मैं देख सकता हूं कि क्या हो रहा है। पहली बार यह मुझे अपना उपयोग बताता है मैं 10 मेग्स पर हूं। जब स्क्रिप्ट खत्म हो जाती है तो मैं 114 मेग्स पर हूं!PHP कचरा संग्रह जबकि स्क्रिप्ट चल रहा है

क्या PHP स्क्रिप्ट चल रहा है, तो क्या यह कचरा संग्रह करता है? या उस स्मृति के साथ क्या हो रहा है? क्या कचरा संग्रह को मजबूर करने के लिए मैं कुछ कर सकता हूं। मेरा स्क्रिप्ट जो काम कर रहा है वह ड्रूपल में दो हजार नोड्स का रात का आयात है। तो यह वही काम कर रहा है कई बार।

कोई सुझाव?

उत्तर

16

कुंजी यह है कि आप unset जैसे ही आपको उनकी आवश्यकता नहीं है, आपके वैश्विक चर शामिल हैं।

आपको स्थानीय चर और ऑब्जेक्ट गुणों के लिए स्पष्ट रूप से अनसेट करने की आवश्यकता नहीं है क्योंकि जब कार्य गुंजाइश से बाहर हो जाता है या ऑब्जेक्ट नष्ट हो जाता है तो ये नष्ट हो जाते हैं।

PHP सभी चर के लिए संदर्भ संख्या रखता है और जैसे ही यह संदर्भ गणना शून्य हो जाती है, उन्हें (अधिकांश स्थितियों में) नष्ट कर देता है। ऑब्जेक्ट्स में एक आंतरिक संदर्भ गणना होती है और वेरिएबल स्वयं (ऑब्जेक्ट संदर्भ) प्रत्येक में एक संदर्भ गणना होती है। जब सभी ऑब्जेक्ट संदर्भ नष्ट हो जाते हैं क्योंकि उनके संदर्भ coutns 0 हिट हो जाते हैं, तो ऑब्जेक्ट स्वयं नष्ट हो जाएगा। उदाहरण:

$a = new stdclass; //$a zval refcount 1, object refcount 1 
$b = $a;   //$a/$b zval refcount 2, object refcount 1 
//this forces the zval separation because $b isn't part of the reference set: 
$c = &$a;   //$a/$c zval refcount 2 (isref), $b 1, object refcount 2 
unset($c);   //$a zval refcount 1, $b 1, object refcount 2 
unset($a);   //$b refcount 1, object refcount 1 
unset($b);   //everything is destroyed 

लेकिन इस परिदृश्य पर विचार:

class A { 
    public $b; 
} 
class B { 
    public $a; 
} 

$a = new A; 
$b = new B; 
$a->b = $b; 
$b->a = $a; 
unset($a); //cannot destroy object $a because $b still references it 
unset($b); //cannot destroy object $b because $a still references it 

ये चक्रीय संदर्भ हैं जहां में आप स्पष्ट रूप से gc_collect_cycles साथ कचरा कलेक्टर आह्वान कर सकते हैं पीएचपी 5.3 के कचरा कलेक्टर किक।।

मैनुअल में Reference Counting Basics और Collecting Cycles भी देखें।

2

जितना संभव हो सके unset() का उपयोग करें, अधिक बार उपयोग की गई मेमोरी की जांच करें। हां, php कुछ स्थितियों पर रनटाइम के दौरान कचरा संग्रह करता है। यहां php.net पर उपयोगी post है।

1

यदि स्मृति इतना बढ़ रही है, तो आप शायद इसे जारी नहीं कर रहे हैं। आपने मेमोरी लीक बनाई है। कचरा संग्रह आपकी मदद नहीं करेगा यदि आप चर को अनसेट नहीं करते हैं, वस्तुओं को नष्ट करते हैं और/या वे दायरे से बाहर जाते हैं।

क्या आप उनके साथ किए जाने के बाद लोड नोड्स को परेशान कर रहे हैं? मैंने PHP स्क्रिप्ट लिखी हैं जो घंटों तक चलती हैं, लाखों डेटाबेस रिकॉर्ड्स को संसाधित करती हैं, बिना किसी समस्या और मेमोरी उपयोग जो एक स्वीकार्य सीमा के भीतर ऊपर और नीचे जाती है।

3

PHP garbage collection काफी हद तक एक संदर्भ काउंटर है (इसमें कुछ चक्र का पता लगाना है।) यदि आप उन संदर्भों को रखते हैं जो अभी भी सुलभ हैं, तो मुक्त होने पर आसानी से जुड़ जाएंगे।

unset() का उपयोग उन फ्री चर के लिए करें जिनका आप अब उपयोग नहीं कर रहे हैं। यदि आप आसानी से चर को ओवरराइट करते हैं (उदाहरण के लिए, शून्य के साथ) यह केवल जीसी को उस चर द्वारा आवश्यक स्थान की मात्रा को कम करने की अनुमति देगा, लेकिन उतना ही असंतुलित नहीं है जो वास्तव में संदर्भित मान के विनाश की अनुमति देता है।

आपको किसी भी संसाधन आदि को ठीक से रिलीज़ करना चाहिए जो आप उपयोग करते हैं।

आप अभी भी रनटाइम के दौरान स्मृति वृद्धि देखेंगे क्योंकि जीसी इसे अपने स्वयं के विघटन पर मुक्त करने के लिए स्वतंत्र है, जैसे कि जब मुफ्त सीपीयू चक्र होते हैं या जब यह स्मृति पर कम चलना शुरू होता है।

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