2009-05-14 14 views
279

जावास्क्रिप्ट कचरा संग्रह क्या है? वेब कोडर के लिए बेहतर कोड लिखने के लिए जावास्क्रिप्ट कचरा संग्रह के बारे में समझना महत्वपूर्ण है?जावास्क्रिप्ट कचरा संग्रह क्या है?

+3

भी http://stackoverflow.com/questions/774357/garbage-collection –

+1

यह भी देखना देखें [कैसे करता है जावास्क्रिप्ट कचरा संग्रहण काम करता है?] (Http://stackoverflow.com/q/4324133/1048572) – Bergi

उत्तर

185

में एरिक Lippert इस विषय के बारे में detailed blog post एक समय पहले लिखा था (अतिरिक्त के साथ उसकी तुलना VBScript) आप इस विषय में रुचि रखते हैं। अधिक सटीक रूप से, उन्होंने JScript लिखा, जो माइक्रोसॉफ्ट का ईसीएमएस्क्रिप्ट का अपना कार्यान्वयन है, हालांकि जावास्क्रिप्ट के समान ही है। मैं कल्पना करता हूं कि आप ग्रहण कर सकते हैं कि अधिकांश एक्सप्लोरर इंटरनेट एक्सप्लोरर के जावास्क्रिप्ट इंजन के लिए समान होंगे। बेशक, कार्यान्वयन ब्राउज़र से ब्राउज़र में भिन्न होगा, हालांकि मुझे संदेह है कि आप कई सामान्य सिद्धांतों को ले सकते हैं और उन्हें अन्य ब्राउज़रों पर लागू कर सकते हैं।

कि पेज से उद्धरित:

JScript एक nongenerational निशान और झाडू कचरा कलेक्टर का उपयोग करता है। यह इस तरह काम करता है:

  • हर चर जो "दायरे में" एक "मेहतर" कहा जाता है। एक स्कैनेंजर किसी संख्या, ऑब्जेक्ट, स्ट्रिंग, जो कुछ भी हो सकता है। हम स्वेवेंजर्स की एक सूची बनाए रखते हैं - स्कैव सूची में आते हैं और जब वे दायरे से बाहर निकलते हैं तो स्कैव सूची में वेरिएबल्स स्थानांतरित होते हैं।

  • हर अब और फिर कचरा संग्राहक चलता है। सबसे पहले यह प्रत्येक ऑब्जेक्ट, वेरिएबल, स्ट्रिंग इत्यादि पर "चिह्न" रखता है - सभी मेमोरी जीसी द्वारा को ट्रैक किया गया। (JScript VARIANT डेटा संरचना आंतरिक रूप से उपयोग करता है और वहाँ कि संरचना में अतिरिक्त अप्रयुक्त बिट्स के बहुत सारे हैं, इसलिए हम अभी उन्हें एक एक निर्धारित किया है।)

  • दूसरा, यह खोजी और पर निशान को साफ करता है स्कैनेंजर संदर्भों के संक्रमणीय बंद । एक मेहतर वस्तु एक nonscavenger वस्तु का संदर्भ तो अगर फिर हम nonscavenger पर बिट्स साफ़ करें, और सब कुछ है कि यह को संदर्भित करता है पर। (मैं मेरी पहले पोस्ट में से एक अलग अर्थ में शब्द "बंद" का उपयोग कर रहा हूँ।)

  • इस बात हम जानते हैं कि सभी स्मृति अभी भी चिह्नित स्मृति जो किसी भी इन-गुंजाइश चर से किसी भी पथ से नहीं पहुँचा जा सकता आवंटित किया जाता है पर। उन वस्तुओं के सभी को को स्वयं को फाड़ने का निर्देश दिया गया है, जो किसी भी परिपत्र संदर्भ को नष्ट कर देता है।

कचरा संग्रहण का मुख्य उद्देश्य वस्तुओं वे बना सकते हैं और उपयोग की स्मृति प्रबंधन के बारे में चिंता नहीं है हालांकि निश्चित रूप से कोई यह कभी कभी परहेज प्रोग्रामर नहीं अनुमति देने के लिए है - यह हमेशा के लिए फायदेमंद है कम से कम एक कचरा विचार है कि कैसे कचरा संग्रह काम करता है।

कुछ विशेष बिंदु हैं जिनके बारे में पता होना चाहिए। इस मामले पर ऐप्पल डेवलपर साइट some guidelines है। वहां से दो महत्वपूर्ण लोग:

  • हटाए गए कथन का उपयोग करें। जब भी आप एक नया कथन का उपयोग कर ऑब्जेक्ट बनाते हैं, तो उसे हटाए गए कथन के साथ जोड़ दें। यह सुनिश्चित करता है कि ऑब्जेक्ट से जुड़ी सारी मेमोरी, जिसमें उसकी संपत्ति का नाम शामिल है, कचरा संग्रह के लिए उपलब्ध है। डिलीट कथन पर "फ्री ऑब्जेक्ट्स" में अधिक चर्चा की गई है।
  • var कीवर्ड का उपयोग करें। विभिन्न कीवर्ड के बिना बनाए गए किसी भी चर को वैश्विक दायरे में बनाया गया है और कभी भी मेमोरी रिसाव के लिए अवसर प्रस्तुत करने वाले कचरे के संग्रह के लिए योग्य नहीं है।

मैं कल्पना कर सकते हैं कि प्रथाओं (विभिन्न ब्राउज़रों में) सभी जावास्क्रिप्ट इंजन के लिए आवेदन करना चाहिए, क्योंकि इससे एक एप्पल साइट से है, वे कुछ हद तक सफारी के लिए विशिष्ट हो सकता है। (शायद कोई इसे स्पष्ट कर सकता है?)

आशा है कि मदद करता है।

+3

सेब डेवलपर साइट पर +1 शानदार लिंक –

+4

लिंक टूटा हुआ है। यह नया स्थान प्रतीत होता है: http://developer.apple.com/safari/library/documentation/ScriptingAutomation/Conceptual/JSCodingGuide/Advanced/Advanced.html –

+0

@ मार्क: इसे इंगित करने के लिए धन्यवाद। पोस्ट अपडेट किया गया है। – Noldorin

1

जावास्क्रिप्ट कचरा संग्रह क्या है?

जांच this

क्या महत्वपूर्ण है एक वेब प्रोग्रामर जावास्क्रिप्ट कचरा संग्रहण, के बारे में बेहतर कोड लिखने के लिए समझने के लिए?

जावास्क्रिप्ट में आपको स्मृति आवंटन और अस्वीकृति की परवाह नहीं है। जावास्क्रिप्ट दुभाषिया को पूरी समस्या की मांग की जाती है। जावास्क्रिप्ट में लीक अभी भी संभव हैं, लेकिन वे दुभाषिया की बग हैं। आप पढ़ सकते हैं और अधिक www.memorymanagement.org

+0

आप सका विस्तृत? – tghw

+0

आपके द्वारा लिंक किए गए लेख में विभिन्न मेमोरी प्रबंधन प्रणालियों में से कौन सा जावास्क्रिप्ट द्वारा उपयोग किया जाता है? _ "जावास्क्रिप्ट में लीक अभी भी संभव हैं, लेकिन वे दुभाषिया की बग हैं।" _ - इसका मतलब यह नहीं है कि जेएस प्रोग्रामर पूरी समस्या को अनदेखा कर सकते हैं, उदाहरण के लिए एक सुंदर प्रसिद्ध जेएस <-> डोम सर्कुलर संदर्भ समस्या है आईई के पुराने संस्करण जो आप अपने जेएस कोड में चारों ओर काम कर सकते हैं। साथ ही, जिस तरह से जेएस काम बंद कर देता है वह डिज़ाइन फीचर है, बग नहीं, लेकिन अगर आप "अनुपयुक्त" बंद करने का उपयोग करते हैं तो आप स्मृति के बड़े हिस्से को जोड़ सकते हैं (मैं _not_ कह रहा हूं 'em का उपयोग नहीं करता)। – nnnnnn

+3

मेमोरी लीक जावास्क्रिप्ट में एक जानवर हैं। यदि आप एक साधारण "कॉलेज प्रोजेक्ट" एप्लिकेशन लिख रहे हैं, तो कोई चिंता नहीं है। लेकिन जब आप उच्च-प्रदर्शन एंटरप्राइज़-स्तरीय ऐप्स लिखना शुरू करते हैं, तो जावास्क्रिप्ट में मेमोरी प्रबंधन जरूरी है। – Doug

51

वृत्तीय संदर्भ से सावधान रहें जब डोम वस्तुओं शामिल कर रहे हैं:

Memory leak patterns in JavaScript

ध्यान रखें कि स्मृति केवल जब वहाँ वस्तु के लिए कोई सक्रिय संदर्भ हैं पुनः दावा किया जा सकता है। यह बंद और घटना हैंडलर के साथ एक आम गड़बड़ी है, क्योंकि कुछ जेएस इंजन जांच नहीं करेंगे कि वास्तव में आंतरिक चर में कौन से चर संदर्भित हैं और केवल संलग्न कार्यों के सभी स्थानीय चर रखें।

function init() { 
    var bigString = new Array(1000).join('xxx'); 
    var foo = document.getElementById('foo'); 
    foo.onclick = function() { 
     // this might create a closure over `bigString`, 
     // even if `bigString` isn't referenced anywhere! 
    }; 
} 

एक अनुभवहीन जे एस कार्यान्वयन bigString रूप में लंबे समय ईवेंट हैंडलर के आसपास है के रूप में जमा नहीं कर सकता:

यहाँ एक सरल उदाहरण है। इस समस्या को हल करने के कई तरीके हैं, उदाहरण के लिए init() (delete के अंत में स्थानीय चर और फ़ंक्शन तर्कों के लिए काम नहीं करेगा: delete ऑब्जेक्ट्स से गुण हटा देता है, और परिवर्तनीय वस्तु अनुपलब्ध है - सख्त मोड में ES5 भी फेंक देगा यदि आप स्थानीय चर को हटाने का प्रयास करते हैं तो ReferenceError!)।

यदि आप स्मृति खपत की देखभाल करते हैं तो मैं जितना संभव हो सके अनावश्यक बंद होने से बचने की सलाह देता हूं।

+19

डीओएम परिपत्र संदर्भ बग जेस्क्रिप्ट के लिए विशिष्ट है - कोई अन्य ब्राउज़र इसे पीड़ित नहीं करता है लेकिन आईई।असल में मुझे पूरा यकीन है कि ईसीएमएस्क्रिप्ट स्पेक स्पष्ट रूप से बताता है कि जीसी ऐसे चक्रों को संभालने में सक्षम होना चाहिए: -/ – olliej

+0

@olliej: मुझे [ईसीएमएस्क्रिप्ट स्पेक] में जीसी का कोई उल्लेख नहीं दिख रहा है (http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf)। –

+0

यह भी देखें http://point.davidglasser.net/2013/06/27/surprising-javascript-memory-leak.html – Christoph

13

अच्छा उद्धरण एक ब्लॉग

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

उदाहरण के लिए:

function makeABigObject() { 
var bigArray = new Array(20000); 
} 

जब आप कि फ़ंक्शन को कॉल करें, JScript घटक एक वस्तु (bigArray नाम) है कि समारोह के भीतर पहुंचा जा सकता है बनाता है। जैसे ही फ़ंक्शन वापस आता है, फिर भी, आप bigArray का "ट्रैक खो देते हैं" क्योंकि अब इसका संदर्भ देने का कोई तरीका नहीं है। खैर, जेस्क्रिप्ट घटक को पता चलता है कि आपने इसका ट्रैक खो दिया है, और इतना बड़ा ऐरे साफ़ हो गया है - इसकी याददाश्त पुनः प्राप्त की गई है। डीओएम घटक में एक ही तरह की चीज काम करती है। यदि आप document.createElement('div'), या कुछ समान कहते हैं, तो DOM घटक आपके लिए एक ऑब्जेक्ट बनाता है। एक बार जब आप उस वस्तु का ट्रैक खो देते हैं, तो डीओएम घटक संबंधित को साफ कर देगा।

13

मेरे सबसे अच्छे ज्ञान के लिए, ऑब्जेक्ट में शेष संदर्भ नहीं होने पर जावास्क्रिप्ट की ऑब्जेक्ट्स कचरा इकट्ठा होती है। यह कुछ ऐसा है जो अपने आप होता है है, लेकिन अगर आप यह कैसे काम करता, सी ++ स्तर पर के बारे में अधिक देखना चाहते हैं, यह समझ में आता है WebKit या V8 source code

पर एक नज़र लेने के लिए आम तौर पर आप इसके बारे में सोचने की जरूरत नहीं है हालांकि, पुराने ब्राउज़र में, आईई 5.5 और आईई 6 के शुरुआती संस्करणों की तरह, और शायद वर्तमान संस्करण, बंद होने से परिपत्र संदर्भ बनाएंगे कि जब अनचेक किया जाता है तो स्मृति को खत्म करना समाप्त हो जाएगा। विशेष मामले में मेरा मतलब बंद होने के बारे में है, यह तब हुआ जब आपने किसी डोम ऑब्जेक्ट में जावास्क्रिप्ट संदर्भ जोड़ा, और एक ऑब्जेक्ट को किसी DOM ऑब्जेक्ट में जोड़ा जो जावास्क्रिप्ट ऑब्जेक्ट को वापस संदर्भित करता था। असल में इसे कभी भी एकत्र नहीं किया जा सकता था, और अंततः ओएस को परीक्षण ऐप्स में अस्थिर बनने का कारण बनता था जो क्रैश बनाने के लिए लुप्त हो गया था। अभ्यास में ये लीक आमतौर पर छोटे होते हैं, लेकिन आपके कोड को साफ रखने के लिए आपको DOM ऑब्जेक्ट को जावास्क्रिप्ट संदर्भ हटा देना चाहिए।

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

+0

जावास्क्रिप्ट -> DOM -> जावास्क्रिप्ट परिपत्र संदर्भ समस्या आईई के नए संस्करणों में हल हो गई है? यदि हां, तो कब से? मैंने सोचा कि यह वास्तुशिल्प रूप से बहुत गहरा था और कभी भी तय होने की संभावना नहीं थी। क्या आपके पास कोई स्रोत है? – erikkallen

+0

बस अजीब तरह से। मैंने मानकों मोड में चल रहे आईई 8 में पागल लीक नहीं देखा है, टूटा हुआ मोड नहीं। मैं अपनी प्रतिक्रिया समायोजित करूंगा। –

+1

@erikkallen: हाँ, जीसी बग आईई संस्करण 8+ में तय किया गया है, क्योंकि पुराने लोग बहुत ही कचरा कचरा संग्रह एल्गोरिदम का उपयोग कर रहे थे, जिसने जीसी को एक दूसरे के संदर्भ में वस्तुओं की एक जोड़ी असंभव बना दिया। नया 'मार्क-एंड-स्वीप' शैली एल्गोरिदम [इसका ख्याल रखना] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management)। –

3

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

सभी जावास्क्रिप्ट इंजनों का अपना कचरा कलेक्टर है, और वे भिन्न हो सकते हैं। अधिकतर समय आपको उनसे निपटने की ज़रूरत नहीं है क्योंकि वे सिर्फ वही करते हैं जो उन्हें करना है।

लेखन बेहतर कोड ज्यादातर कितना अच्छा आप प्रोग्रामिंग सिद्धांतों, भाषा और विशेष रूप से कार्यान्वयन में पता है की निर्भर करता है।

1

खिड़कियों पर आप Drip.exe का उपयोग मेमोरी लीक पाते हैं या यदि आपका मुक्त मेम दिनचर्या काम करता है की जाँच कर सकते हैं।

यह वास्तव में आसान है, बस एक वेबसाइट URL दर्ज करें और आप एकीकृत आईई रेंडरर की स्मृति की खपत देखेंगे। फिर, ताज़ा मारा अगर स्मृति बढ़ जाती है, तो आप वेब पेज पर कहीं न कहीं एक स्मृति रिसाव पाया। लेकिन यह भी बहुत उपयोगी है कि आईई के लिए मेमोरी काम मुक्त करने के लिए दिनचर्या क्या है।

6

कचरा संग्रह (जीसी) उन वस्तुओं को हटाकर स्वचालित स्मृति प्रबंधन का एक रूप है जो अब और आवश्यक नहीं है। इस स्मृति स्थान

देखते हैं मुक्त -

1 - अपनी स्मृति अंतरिक्ष का आवंटन आप

2 की जरूरत है - कुछ प्रसंस्करण

3 कार्य करें:

स्मृति के साथ किसी भी प्रक्रिया सौदा निम्न चरणों का पालन दो मुख्य एल्गोरिदम का पता लगाने के लिए उपयोग किया जाता है कि अब कौन सी वस्तुओं की आवश्यकता नहीं है।

संदर्भ गिनती कचरा संग्रहण: यह कलनविधि, की "एक वस्तु कोई अन्य वस्तु यह करने के लिए संदर्भित किया है" के लिए "एक वस्तु की अब कोई आवश्यकता नहीं है" परिभाषा को कम कर देता वस्तु हटा दिया जाएगा अगर यह

के लिए कोई संदर्भ बिंदु

मार्क-एंड-स्वीप एल्गोरिदम: प्रत्येक ऑब्जेक्ट को रूट स्रोत से कनेक्ट करें। कोई ऑब्जेक्ट रूट या अन्य ऑब्जेक्ट से कनेक्ट नहीं होता है। इस वस्तु को हटा दिया जाएगा।

वर्तमान में दूसरे एल्गोरिदम का उपयोग कर अधिकांश आधुनिक ब्राउज़र।

+1

और इसका एक स्रोत जोड़ने के लिए, एमडीएन देखें: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management – Xenos

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