2011-08-18 6 views
6

स्मृति के थकने वाले कोड के एक टुकड़े को डिबग करते समय, मुझे एक बहुत ही रोचक समस्या मिली, और सबसे महत्वपूर्ण बात यह नहीं है कि मुझे इसे कैसे ठीक किया जाए।अपने आप को संदर्भों के साथ किसी ऑब्जेक्ट को नष्ट करना

एप्लिकेशन में लगभग Survey ऑब्जेक्ट शामिल है, जिसमें Question ऑब्जेक्ट्स शामिल हैं। प्रश्न ऑब्जेक्ट्स में सर्वेक्षण के संदर्भ में वे संदर्भ हैं, उदाहरण के लिए अन्य प्रश्नों से उत्तर प्राप्त करने में सक्षम होने के लिए इसकी आवश्यकता है।


निम्नलिखित पाश स्मृति अतिप्रवाह पैदा कर रहा था:

foreach ($survey_ids_arr as $survey_id) { 
    $Survey = new Survey($survey_id); 
} 

कुछ भी नहीं है वास्तव में विदेशी सर्वेक्षण निर्माता में हो रहा है;

  • डेटाबेस
  • डेटाबेस
  • से सभी सवालों के 'गुण प्राप्त करने में कठिनाई प्रत्येक प्रश्न के लिए एक प्रश्न वस्तु बनाने से उसके गुण प्राप्त करने में कठिनाई
  • ($ इस के लिए एक संदर्भ गुजर) एक करने के लिए सभी प्रश्न वस्तुओं को जोड़ने आंतरिक सरणी

और कोड को देखने से, आप कहेंगे कि प्रत्येक पुनरावृत्ति में वस्तु स्मृति से साफ़ हो जाती है क्योंकि $ सर्वेक्षण चर अधिलेखित होता है। सही?? गलत :)

के रूप में स्क्रिप्ट लूप के माध्यम से चला जाता है स्मृति ढेर है - memory_get_usage() कॉल जोड़ने पता चलता है कि सर्वेक्षण वस्तु द्वारा प्रयुक्त स्मृति के रूप में उम्मीद मुक्त नहीं है, पल किसी अन्य वस्तु $Survey चर को सौंपा गया है पर । लूप के अंत में unset($Survey) को कॉल करने से स्मृति को मुक्त नहीं किया जाता है।


अपराधी $this के लिए संदर्भ है कि निर्माण पर सवाल वस्तुओं को पास किया जाता है। इन संदर्भों को रोकने वस्तु मेमोरी से साफ़ किए जाने - php.net राज्यों पर पुस्तिका के रूप में:

नाशक पद्धति के रूप में जल्द ही एक विशेष वस्तु के सभी संदर्भ के रूप में

निकाल दिए जाते हैं तो कहा जाएगा वस्तु को साफ होने से रोकता है, क्या इसमें संदर्भ है। अच्छा, हुह? :)

तो, समस्या यह है कि मेरी वस्तु एक स्मृति हत्यारा है। दुर्भाग्य से, मैं एक समाधान के बारे में नहीं सोच सकता (एक बदसूरत विधि लिखने के अलावा जो प्रश्नों को साफ़ करता है और लूप से कॉल करता है)। सर्वेक्षण में विनाशक एक विकल्प नहीं है; जैसा ऊपर बताया गया है उसे नहीं कहा जाता है क्योंकि प्रश्न ऑब्जेक्ट्स में अभी भी संदर्भ हैं।

कोई विचार? किसी को पहले से ही इस समस्या में भाग लेना होगा - माता-पिता युक्त-बच्चे-वस्तुएं असामान्य वास्तुकला नहीं है, है ना?

+0

समस्या आपके डिज़ाइन में एक विरोधाभास है: आप ऑब्जेक्ट को स्मृति से साफ़ करने के लिए रोकना चाहते हैं लेकिन आप इसे साफ़ करना चाहते हैं? – m0skit0

+1

यह समस्या php 5.3 में हल हो गई है। आप किस PHP संस्करण का उपयोग करते हैं? – J0HN

+0

आप सही हैं J0HN, मुझे बस बग रिपोर्ट मिली! https://bugs.php.net/bug.php?id=33595 – Rijk

उत्तर

2

तो, यहां जवाब है: PHP 5.3 पर स्विच करें, क्योंकि यह समस्या resolved है। यदि आपको PHP < 5.3.0 के साथ काम करना है, तो सर्कल संदर्भों में कैप्चर की गई वस्तुओं को मुक्त करना आपकी ज़िम्मेदारी है।एक संभावित तरीका यह है कि विशेष विधि पेश करना है जो उन्हें GC

पीएस द्वारा एकत्रित करने के लिए बाल वस्तुओं के लिंक को बंद कर देगा। किसी के लिए भी उपयोगी हो सकता है, Doctrine 1.2 मॉडल में ऐसे लिंक हैं, इसलिए यह स्मृति रिसाव के लिए विषय है, खासकर यदि आप अपने डेटाबेस से कई इकाइयां प्राप्त करते हैं। यदि आप इन मुद्दों का सामना कर रहे हैं, तो कोशिश करें (1) प्राप्त इकाइयों की मात्रा को कम करें (उदाहरण के लिए सरणी के रूप में हाइड्रेट), (2) कच्चे एसक्यूएल अनुरोधों के साथ प्रक्रिया इकाइयां।

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

  • कोई संबंधित समस्या नहीं^_^