2010-08-01 11 views
7

मेरे पास नीचे दिया गया कार्य है जिसे मैं लूप में अक्सर कॉल करता हूं।PHP कचरा संग्रह बेकार है या यह सिर्फ मुझे है?

मैं 5 मिनट तक इंतजार कर रहा था क्योंकि स्मृति 1 एमबी से 156 एमबी तक चढ़ गई थी। PHP के कचरा कलेक्टर को चालू नहीं करना चाहिए और इसे किसी बिंदु पर कम करना चाहिए ?!

क्या ऐसा इसलिए है क्योंकि मैंने 256 एमबी पर मेमोरी सीमा निर्धारित की है?

गूंज बिंदु 2,3,4 पर इसकी सुंदर निरंतर स्मृति उपयोग। यह बिंदु 4 पर मेरा आधा मेग नीचे चला जाता है लेकिन बिंदु 1 वह जगह है जहां मुख्य स्मृति वृद्धि होती है। शायद file_get_html की वजह से स्मृति में एचटीएमएल फाइल लोड हो रही है।

हालांकि मैं चर $html के स्पष्ट और अनसेट का ख्याल रखूंगा?

function get_stuff($link, $category){ 

    $html = file_get_html(trim("$link")); 

    $article = $html->find('div[class=searchresultsWidget]', 0); 

    echo '1 - > '.convert(memory_get_usage(true)).'<br />'; 

    foreach($article->find('h4 a') as $link){ 

     $next_url = 'http://new.mysite.com'.$link->href; 

     $font_name = trim($link->plaintext);   

     $html = file_get_html(trim("$next_url")); 

     $article = $html->find('form[class=addtags]', 0); 

     $font_tags = ''; 

     foreach($article->find('ul[class=everyone_tags] li a span') as $link){ 

      $font_tags .= trim($link->innertext).','; 

     } 

     echo '2 - > '.convert(memory_get_usage(true)).'<br />'; 

     $font_name = mysql_real_escape_string($font_name); 
     $category = mysql_real_escape_string($category); 
     $font_tags = mysql_real_escape_string($font_tags); 

     $sql = "INSERT INTO tag_data (font_name, category, tags) VALUES ('$font_name', '$category', '$font_tags')"; 

     unset($font_tags); 
     unset($font_name); 
     unset($category); 

     $html->clear(); 

     mysql_query($sql); 

     unset($sql); 

     echo '3 - > '.convert(memory_get_usage(true)).'<br />';  

} 

    unset($next_url); 
    unset($link); 
    $html->clear(); 
    unset($html); 
    unset($article); 

    echo '4 - > '.convert(memory_get_usage(true)).'<br />'; 

} 

जैसा कि आप देख सकते हैं, मैंने परेशान होने का उपयोग करने का प्रयास किया। यद्यपि यह अच्छा नहीं है जैसा कि मैं समझता हूं, जैसे ही मैं इसे कॉल करता हूं, यह स्मृति को "अनसेट" नहीं करेगा।

इस बात की कोई मदद के लिए धन्यवाद कि मैं स्मृति के ऊपर की वृद्धि को कैसे कम कर सकता हूं।

+6

मुझे अपने प्रश्न के लिए एक नकारात्मक प्रतिनिधि मिल गया है? स्टैक ओवरफ्लो से उपयोगी सूचनाओं की तरह कहें। अगर आप ऐसा करते हैं, तो केवल नकारात्मक प्रतिनिधि न करें, टिप्पणी के द्वारा इसका पालन करें। – Abs

+1

मुझे यह वास्तव में एक अच्छा सवाल मिल रहा है। शायद यह शब्द 'चूसना' है जो इसे उत्तेजित करता है। Upvoted। – Mchl

+0

PHP में http अनुरोध द्वारा उपयोग की जाने वाली सभी मेमोरी अनुरोध के अंत में टूट गई है। हालांकि अनुरोध पर संसाधित होने पर जीसी स्मृति का प्रबंधन करने के लिए प्रयोग किया जाता है। मेरा मानना ​​है कि यह सरल रेफ गिनती है। – seand

उत्तर

8

वहाँ file_get_html() के साथ एक ज्ञात स्मृति रिसाव है: http://simplehtmldom.sourceforge.net/manual_faq.htm#memory_leak

समाधान

$html->clear(); 

जो तुम कर रहे हो उपयोग करने के लिए है, लेकिन: आप $ का उपयोग कर रहे एचटीएमएल के अंदर और बाहर की पाश। लूप के अंदर आप $ html-> clear() को कॉल कर रहे हैं, और उसके बाद अपने फ़ंक्शन के अंत में $ html-> clear() फिर से (मुझे लगता है कि मैं अपना प्रारंभिक file_get_html() ऑब्जेक्ट संदर्भ पकड़ लेता हूं)। वह अंतिम कॉल कुछ भी नहीं करता है। आप शुरुआती $html = file_get_html() कॉल के साथ मेमोरी लीक कर रहे हैं।

अपने लूप के अंदर एक अलग चर ($ html1, शायद?) का उपयोग करने का प्रयास करें और देखें कि क्या होता है।

+0

अच्छा सुझाव, मैं कोशिश कर रहा हूं कि जब यह परीक्षण मैं समाप्त हो रहा हूं। क्या आपको लगता है कि कमांड लाइन से इस PHP स्क्रिप्ट को चलाने से कोई फर्क पड़ता है? यह सिर्फ ब्याज से बाहर है। – Abs

+0

"आप प्रारंभिक $ html = file_get_html() के साथ मेमोरी सहयोगी खो रहे हैं।" हम? इसका क्या मतलब है? – Artefacto

+0

यह एक अच्छा सुझाव था। यह स्मृति वृद्धि की दर में कमी को कम करने में कामयाब रहा! यह अभी तक इस बिंदु पर 10 एमबी नहीं चला है। 120 एमबी या इससे भी पहले होने से पहले! मुझे लगता है कि यह अच्छी तरह से काम कर रहा है जेसनबार धन्यवाद! :) – Abs

3

कचरा कलेक्टर का उद्देश्य पूरी तरह परिपत्र संदर्भों को पकड़ने के लिए है।

वहाँ कोई नहीं कर रहे हैं, चर तुरंत एक बार उनके संदर्भ गिनती 0.

हिट मैं सलाह नहीं देते कि आप unset उपयोग करते हैं, असाधारण मामलों को छोड़कर समाप्त हो जाते। इसके बजाय फ़ंक्शंस का उपयोग करें और मेमोरी पुनः दावा करने के दायरे से बाहर निकलने के लिए चर पर भरोसा करें।

इसके अलावा, हम आपको यह वर्णन नहीं कर सकते कि वास्तव में क्या खुशी है क्योंकि हमें यह जानना होगा कि सरल डॉम पार्सर क्या कर रहा है। संभावित रूप से एक संदर्भ रखने वाले परिपत्र संदर्भ या वैश्विक संसाधन हैं, लेकिन यह जानना मुश्किल होगा।

reference counting basics और collecting cycles देखें।

+0

हू? कचरा संग्रह संदर्भ-गिनती का एक विकल्प है, और इसका परिपत्र संदर्भों द्वारा मूर्ख नहीं होने का उल्लेखनीय लाभ है। –

+2

@ स्टीवन इसका मतलब यह नहीं है कि दोनों चीजें PHP में उपयोग नहीं की जाती हैं। – Artefacto

+0

दोनों का उपयोग करना निश्चित रूप से संभव है, खासकर जब एक सिस्टम दूसरे के साथ इंटरफेसिंग कर रहा हो। उदाहरण के लिए, एक COM ऑब्जेक्ट को कॉल करने वाला एक .NET ऐप पूर्व के लिए जीसी है लेकिन उत्तरार्द्ध के लिए संदर्भ गिनती है और इसे दो सहयोग करना है। तो मैं क्या पूछ रहा हूं कि PHP एक या दूसरे या दोनों का उपयोग करता है (और यदि ऐसा है, कब)? –

2

PHP में उचित कचरा कलेक्टर until 5.3 नहीं था। यह मूल रूप से केवल संदर्भ गणना का उपयोग करता है, जो स्क्रिप्ट समाप्त होने तक परिपत्र संदर्भ छोड़ देगा (उदा। $a =& $a परिपत्र है)। साथ ही, डीआईडी ​​के क्लीनअप कोड केवल तभी चलेंगे जब मेमोरी दबाव की आवश्यकता होती है। जैसे यदि नई मुक्त स्मृति की आवश्यकता नहीं है तो एक महंगा सफाई चक्र करने में कोई बात नहीं है।

5.3 के रूप में, एक उचित कचरा कलेक्टर है, और आप इसे gc_enable() और gc_collect_cycles() के साथ चलाने के लिए मजबूर कर सकते हैं।

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