5

मेरे पास जावास्क्रिप्ट कचरा संग्रह/स्मृति रिसाव प्रश्न है। मैं ओएस एक्स 10.8.4 पर क्रोम 28.0.1500.71 का उपयोग कर रहा हूं।जावास्क्रिप्ट क्लोजर मेमोरी लीक

निम्नलिखित कोड me द्वारा आयोजित की गई जगह को कभी भी अस्वीकार नहीं करता है और मैं इस बारे में अनजान हूं कि क्यों।

var MyClass = function() { 
    this.x = 1; 

    var self = this; 
    this.do_thing = function() { 
     self.x++; 
    }; 
}; 
MyClass.prototype.destroy = function() { 
    delete this.do_thing; 
}; 

var me = new MyClass(); 
me.do_thing(); 
me.destroy(); 
me = null; 

// the MyClass object formerly known as 'me' is still allocated here 
// (as evidenced by Chrome's heap profiler) 

क्रोम अभिव्यक्ति new MyClass() (उद्देश्य यह है कि menull करने के लिए सेट किए जाने से पहले की ओर इशारा) स्मृति में है क्योंकि यह me.do_thing() करने के लिए कॉल में self द्वारा संदर्भित है के द्वारा बनाई गई वस्तु रखने के लिए लगता है। हालांकि, मैंने destroy() पर कॉल सोचा होगा, जो me.do_thing को अनसेट करता है, new MyClass() कॉल में कन्स्ट्रक्टर (self) के दायरे में चर को फेंक देगा।

मैंने अंडरस्कोर.जेएस के _.bind फ़ंक्शन का उपयोग करने का भी प्रयास किया है, लेकिन यहां वर्णित एक ही अनसुलझा समस्या में चलाया गया है: Instances referenced by 'bound_this' only are not garbage collected

+0

कृपया "वैश्विक चर 'me'" और "MyClass' ऑब्जेक्ट" के बीच सटीक और अंतर करें। चर निश्चित रूप से स्मृति में रहेगा, लेकिन यह कोई समस्या नहीं है (और यदि यह है, तो आप इसे 'विंडो' से हटा सकते हैं, सिमोनलेंग के उत्तर देखें)। क्या क्रोम इंगित करता है कि 'MyClass' ऑब्जेक्ट अभी भी जिंदा है? – delnan

+0

उचित बिंदु; यह 'MyClass' ऑब्जेक्ट है जिसे * 'i' द्वारा संदर्भित किया गया था जिसे कभी भी हटाया नहीं जाता है। मैंने यह स्पष्ट करने के लिए अपने प्रश्न के शब्द को अद्यतन किया। – soney

+1

ऐसा लगता है कि वी 8 में एक बग है, मैंने इसके खिलाफ एक मुद्दा खोला: https://code.google.com/p/v8/issues/detail?id=2791 –

उत्तर

0

मुझे अभी भी विंडो ऑब्जेक्ट की एक संपत्ति है, भले ही आप इसे शून्य पर सेट करें। इस प्रकार "मैं" अभी भी स्मृति में है।

मुझे लगता है कि इस मदद मिल सकती है:

window.me = new MyClass(); 
me.do_thing(); 
delete window.me; 
+0

यह स्निपेट अभी भी 'MyClass' ऑब्जेक्ट को आवंटित करता है मेरा ब्राउज़र – soney

1

मैं क्यों यह कचरा एकत्र, लेकिन प्रोटोटाइप के बजाय उदाहरण के लिए विधि को नष्ट जोड़ने और शून्य पर self की स्थापना नहीं है पता नहीं है, जाहिरा तौर पर काम करेंगे :

var MyClass = function() { 
    this.x = 1; 

    var self = this; 
    this.do_thing = function() { 
     self.x++; 
    }; 

    this.destroy = function() { 
     delete this.do_thing; 
     self = null; 
    }; 
}; 

var me = new MyClass(); 
me.do_thing(); 
me.destroy(); 
me = null; 
+0

दिलचस्प है, हालांकि मैं अभी भी उत्सुक हूं कि 'स्वयं' को – soney

+0

@ मैन्युअल रूप से मैन्युअल रूप से निपटाने की आवश्यकता क्यों है, ऐसा लगता है कि लाइन 'self.x ++' पंक्ति में 'self.x' के असाइनमेंट के साथ इसका कुछ संबंध है। यदि आप उस लाइन को 'self.x' वापस करने के लिए बदलते हैं, तो उसे कचरा भी मिल जाएगा। – basilikum

0

MyClass एक वैश्विक चर है। यह ब्राउज़र वातावरण में विंडो ऑब्जेक्ट की एक संपत्ति भी है। यह एक कचरा नहीं है इसलिए इसे इकट्ठा नहीं किया जाएगा।

+0

जबकि 'MyClass' फ़ंक्शन स्थान ले रहा है, मैं अभिव्यक्ति' नया MyClass() 'द्वारा बनाई गई वस्तु का जिक्र कर रहा हूं। 'Me' को शून्य करने के बाद सेट किया गया है, इसके पास इसका कोई और संदर्भ नहीं होना चाहिए और इसे एकत्रित किया जाना चाहिए। – soney

+0

ऑब्जेक्ट जीसी द्वारा एकत्र किया जाएगा, बस तुरंत नहीं। एक नया हीप स्नैपशॉट रीफ्रेश करने और जेनरेट करने का प्रयास करें, आपको कोई MyClass ऑब्जेक्ट नहीं दिखाई देगा। – simonleung

0

एक बग की तरह लग रहा है। बीटीडब्ल्यू me.destroy() आवश्यक नहीं है। इसे इसके बिना हटा दिया जाना चाहिए।

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