आप यहाँ क्या कर रहे के बारे में सोचने की जरूरत है। यदि list
की कक्षा थ्रेड-सुरक्षित नहीं है, तो आप को इस कोड के साथ पूरी तरह से newList
--a सीएमई को अपनी समस्याओं का कम से कम नष्ट कर सकते हैं। (मैं एक वर्ग का सुझाव दूंगा जो सीएमई नहीं फेंकता है, लेकिन इस मामले में एक सीएमई अच्छा चीज है।) ध्यान दें: यह कोड परीक्षण करना मुश्किल है। आपको हर विफलता के बीच कहीं शून्य और अरबों समस्या-मुक्त रनों के बीच कहीं मिलेगा, और असफलता बहुत सूक्ष्म हो सकती है, हालांकि वे बड़े पैमाने पर और तर्कसंगत स्पष्टीकरण से अधिक होने की संभावना है।
सबसे तेज़ फिक्स list
लॉक करना है। आप इसे हर जगह लॉक करना सुनिश्चित करना चाहते हैं; आप सूची को वास्तव में लॉक नहीं कर रहे हैं, आप उस कोड के ब्लॉक को लॉक कर रहे हैं जिसे आप एक्सेस कर रहे हैं। आपको सभी एक्सेस लॉक करना होगा। नकारात्मकता यह है कि नई सूची बनाई जा रही है, जबकि आप अन्य धागे को अवरुद्ध करेंगे। यह वास्तव में जाने का रास्ता है। हालांकि, यदि आप कहते हैं, "सूची बहुत बड़ी है", तो आप प्रदर्शन के बारे में चिंतित हो सकते हैं, इसलिए मैं आगे बढ़ूंगा ...
newList
को अपरिवर्तनीय माना जाता है और यह आप कर सकते हैं एक बार बनाया गया इसका लगातार उपयोग। बहुत सारे कोड अब newList
समस्याओं के बिना और असंगतताओं के डर के बिना पढ़ सकते हैं। लेकिन प्रारंभिक सृजन के साथ अभी भी पकड़ है।
अगला चरण list
को java.util.ConcurrentLinkedQueue बनाना है। (एक समवर्ती नक्शा है और सेट करें यदि आपको कुछ फैनसीयर चाहिए।) इस चीज़ में धागे का एक गुच्छा हो सकता है जबकि एक गुच्छा अधिक जोड़ दिया जाता है और इसे हटाया जाता है, और यह हमेशा काम करता है। इसमें शामिल नहीं हो सकता है, लेकिन एक इटरेटर एक अनंत लूप में नहीं जायेगा (जैसा कि list
एक java.util.LinkedList थे) हो सकता है। इससे newList
एक कोर पर बनाया जाता है जबकि आपका अन्य धागा दूसरे पर काम करता है।
डाउनसाइड्स: यदि list
एक ऐरेलिस्ट था, तो आपको समवर्ती कक्षा में स्विच करने के लिए थोड़ा सा काम मिल सकता है। समवर्ती कक्षाएं अधिक स्मृति का उपयोग करती हैं और आम तौर पर ऐरेलिस्ट से धीमी होती हैं। अधिक महत्वपूर्ण: list
की सामग्री असंगत हो सकती है। (असल में, आपके पास पहले से ही यह समस्या है।) आप अन्य थ्रेड में एक ही समय में ए और बी प्रविष्टियां जोड़ या निकाल सकते हैं, और उम्मीद कर सकते हैं कि या तो दोनों या तो न तो newList
में होंगे, वास्तव में यह केवल एक के लिए आसान है वहां रहें, किसी के जोड़े जाने या हटाने के बाद इटेटरेटर आ रहा है लेकिन दूसरे के सामने है। (सिंगल कोर मशीनों में इस समस्या को उतना ही नहीं है।) लेकिन यदि list
पहले से ही स्थिर, विकृत प्रवाह में होने के बारे में सोचा गया है, तो यह वही हो सकता है जो आप चाहते हैं।
एक और, अलग, साइड इफेक्ट: आपको बड़े सरणी और चीजों का उपयोग करने के लिए सावधान रहना होगा (जैसे ऐरेलिस्ट और हैशटेबल)। जब आप प्रविष्टियों को हटाते हैं तो वे कम जगह का उपयोग नहीं करते हैं, इसलिए आप अपने अधिकांश मेमोरी को छेड़छाड़ करने वाले छोटे डेटा वाले बड़े सरणी के समूह के साथ समाप्त कर सकते हैं।
इससे भी बदतर, जब आप प्रविष्टियां जोड़ते हैं, तो वे अपनी पुरानी सरणी मुक्त करते हैं और एक नया, बड़ा, आवंटित करते हैं जिसके परिणामस्वरूप मुक्त स्मृति खंडित होती है। यही है, मुफ्त मेमोरी ज्यादातर पुराने सरणी से निकलती है, जिनमें से कोई भी अगले आवंटन के लिए उपयोग करने के लिए पर्याप्त नहीं है। कचरा कलेक्टर यह सब डिफ्रैगमेंट करने का प्रयास करेगा, लेकिन यह बहुत काम है और जीसी मुक्त ब्लॉकों को पुनर्व्यवस्थित करने के लिए समय निकालने के बजाय मेमोरी अपवादों को फेंकने के इच्छुक है, इसलिए यह आपको सबसे बड़ा-अभी तक स्मृति ब्लॉक प्राप्त कर सकता है बस अनुरोध किया। इसलिए जब आप अपनी स्मृति का केवल 10% उपयोग में हैं तो आपको आउट-ऑफ-मेमोरी त्रुटि मिलती है।
Arrays सबसे तेज़ चीज चल रही है, लेकिन आपको देखभाल के साथ बड़े लोगों का उपयोग करने की आवश्यकता है। प्रत्येक आवंटन और मुफ्त से अवगत रहें। उन्हें एक उचित प्रारंभिक आकार दें ताकि वे अंतरिक्ष को पुन: आवंटित नहीं कर सकें। (दिखाओ कि आप एक सी प्रोग्रामर हैं।) अपने जीसी के लिए दयालु रहें। यदि आपको बड़ी सूचियों को बनाना और मुक्त करना और आकार बदलना चाहिए, तो लिंक्ड क्लास का उपयोग करने पर विचार करें: लिंक्डलिस्ट, ट्रीमैप, कंसूरेंट लिंक्ड क्यूयू, आदि। वे केवल स्मृति की छोटी बिट्स का उपयोग करते हैं, और जीसी के उनसे प्यार करते हैं।
एक 'Collections.synchronizedList' (सूची) इस पर बार-बार दोहराना के साथ एक सीएमई प्राप्त कर सकते हैं जब तक कि यह' सिंक्रनाइज़ किया गया है { } ' –
यिक्स, दाएं @ पीटर, धन्यवाद। मैं जवाब ठीक कर दूंगा। – Gray
मैं सूची आकार 1000000 के साथ व्यावहारिक रूप से सीएमई प्राप्त नहीं कर सका। सरणी सूची के विशेष मामले में जहां बैक किए गए सरणी को System.arraycopy के माध्यम से कॉपी प्रतिलिपि में कॉपी किया गया है, क्या यह वर्तमान सरणी का स्नैपशॉट प्राप्त करेगा? सूची का आकार बदलना प्रभावित करेगा? – Sushant