PHP मेमोरी प्रबंधन: गार्बेज कलेक्टर कैसे काम करता है

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

PHP में मेमोरी की चिंता क्यों करें?

ज़्यादातर PHP डेवलपर्स सोचते हैं कि मेमोरी एक अंतहीन संसाधन है। दस लाख एलिमेंट वाला array चाहिए? लीजिए। कोई object बनाया और भूल गए? कोई बात नहीं, PHP खुद साफ कर देगा। लेकिन जब आपका प्रोजेक्ट Allowed memory size exhausted एरर देने लगे या अचानक धीमा हो जाए, तब समझ आता है कि असल में अंदर क्या हो रहा है।

आज हम PHP के मेमोरी और गार्बेज कलेक्टर (GC) के बारे में गहराई से जानेंगे। आप सीखेंगे कि PHP रेफरेंस कैसे गिनता है, साइक्लिक रेफरेंस क्यों खतरनाक हैं, और GC को अपने पक्ष में कैसे काम में लाएं। चलिए शुरू करते हैं!

PHP मेमोरी प्रबंधन: रिक्वेस्ट से रिस्पॉन्स तक

C या C++ के विपरीत, जहां आप खुद मेमोरी आवंटित और मुक्त करते हैं, PHP Zend Engine के ज़रिए काम करता है। हर PHP प्रोसेस का अपना मेमोरी पूल होता है। जब आप लिखते हैं:

$data = [1, 2, 3];

PHP array के लिए मेमोरी आवंटित करता है, वैल्यू सेव करता है, और refcount (रेफरेंस काउंट) बढ़ाता है। जब तक कोई $data वेरिएबल को रेफर कर रहा है, मेमोरी मुक्त नहीं होती।

लेकिन जैसे ही आप करते हैं:

unset($data);

refcount शून्य हो जाता है, और Zend Engine तुरंत मेमोरी वापस पूल में भेज देता है। बिल्कुल सरल और तेज़। हालांकि, कुछ बारीकियाँ हैं…

रेफरेंस अंकगणित: refcount और is_ref

PHP में हर वेरिएबल एक zval स्ट्रक्चर है, जिसमें वैल्यू, टाइप, is_ref फ्लैग (क्या यह रेफरेंस है) और refcount होता है। उदाहरण देखें:

$a = "Hello";
$b = $a;  // refcount बढ़कर 2 हो जाता है (copy-on-write)
$b = "World"; // अब $a और $b अलग zval हैं, "Hello" का refcount घटकर 1 हो जाता है

इसे copy-on-write (लिखने पर कॉपी) कहते हैं। जब तक आप वैल्यू नहीं बदलते, PHP एक ही मेमोरी एरिया का उपयोग करके मेमोरी बचाता है। लेकिन जैसे ही आप वेरिएबल बदलते हैं, एक कॉपी बन जाती है। चालाकी है, है ना?

गार्बेज कलेक्टर (GC): जब refcount काम नहीं करता

सामान्य रेफरेंस काउंटिंग 99% मामलों में ठीक काम करती है। लेकिन एक समस्या है — साइक्लिक रेफरेंस। मान लीजिए, दो object एक-दूसरे को रेफर करते हैं:

class Node {
    public $next;
}

$a = new Node();
$b = new Node();
$a->next = $b;
$b->next = $a;

unset($a);
unset($b);

unset के बाद भी दोनों objects का refcount = 1 है (हर एक दूसरे को रेफर कर रहा है)। ये कोड से एक्सेस नहीं हो सकते, लेकिन मेमोरी मुक्त नहीं होती। यही साइक्लिक रेफरेंस है।

अगर ऐसे object ज़्यादा हों, तो मेमोरी लीक होने लगती है। इससे निपटने के लिए PHP 5.3 से पूर्ण गार्बेज कलेक्टर (GC) शामिल किया गया।

PHP में GC कैसे काम करता है?

गार्बेज कलेक्टर हर कोड लाइन पर नहीं चलता। यह तब सक्रिय होता है जब रूट बफर (संभावित साइक्लिक रेफरेंस की सूची) भर जाता है। डिफ़ॉल्ट रूप से इसका आकार 10,000 एलिमेंट है। जब बफर भर जाता है, GC यह एल्गोरिदम चलाता है:

  • रूट्स स्कैन करता है — उन सभी zval को ढूंढता है जिनका refcount > 0 है और जो साइकिल का हिस्सा हो सकते हैं।
  • refcount घटाता है — सभी चाइल्ड एलिमेंट के लिए (जैसे कोई रेफरेंस न हो)।
  • जांच करता है — अगर घटाने के बाद refcount शून्य हो जाता है, तो यह "कचरा" है और इसे हटाया जा सकता है।
  • बहाल करता है — जो कचरा नहीं है, उनका refcount वापस लाता है और मेमोरी मुक्त करता है।

इस प्रक्रिया को garbage collection कहते हैं। आप इसे जबरदस्ती चला सकते हैं:

gc_collect_cycles();

लेकिन हर छोटी बात पर इसे न चलाएं — यह एक भारी ऑपरेशन है।

PHP में मेमोरी लीक कैसे ट्रैक करें?

अगर आपकी स्क्रिप्ट लंबे समय तक चलती है (जैसे क्यू वर्कर या डेमॉन), तो मेमोरी लीक गंभीर हो सकती है। यहां कुछ उपकरण हैं:

ब्लॉग

पुस्तक अनुशंसाएँ