दिलचस्प पोस्ट
WKWebView में मूल कोड से जावास्क्रिप्ट फ़ंक्शन को कॉल करें ड्यूल सिम कार्ड एंड्रॉइड मैं सी # / .NET में एक एसएफटीपी सर्वर पर एक फाइल कैसे अपलोड कर सकता हूं? एप्लिकेशन के लिए डिफ़ॉल्ट आईओएस स्थानीय सूचना शैली सेट करें त्रुटि: लापता वर्ग गुणों को बदलना जावा में एक सिंक्रनाइज़ किए गए विधि और सिंक्रनाइज़ ब्लॉक के बीच अंतर क्या है? लंबाई क्यों 2 तत्वों के साथ एक ट्यूपल के लिए 1 देता है, और अधिक तत्वों के साथ ट्यूपल के लिए एक त्रुटि देता है? छिपे वाले बहुभुज वाले जीगोप्लोट में चोर्पलथ मानचित्र क्यों नहीं eigenclass self.class के बराबर है, जब ऐसा दिखता है? कस्टम कॉन्फ़िगरेशन फ़ाइल को सी # (फ्रेमवर्क 4.0) में पढ़ें जावास्क्रिप्ट फ़ंक्शन संदर्भ गलत क्या git में छिपाना सामग्री का पूर्वावलोकन करना संभव है? स्ट्रिंग से वेब वर्कर कैसे बनाऊँ? मैं मोंगोज़ में अलग-अलग मानों के लिए कैसे पूछूं? एक ग्राफ़ में प्लॉट एकाधिक बॉक्सप्लेट

कुछ जावा मेमोरी प्रबंधन सर्वोत्तम अभ्यास क्या हैं?

मैं पिछले डेवलपर से कुछ एप्लिकेशन ले रहा हूं I जब मैं एलेप्से के माध्यम से अनुप्रयोग चलाता हूं, तो मुझे मेमोरी उपयोग दिखाई देता है और ढेर का आकार बहुत ज्यादा होता है I आगे की जांच करने के बाद, मैं देखता हूं कि वे किसी ऑब्जेक्ट को एक लूप में और साथ ही अन्य चीजों में बना रहे थे।

मुझे जाना और कुछ साफ करना शुरू कर दिया। लेकिन जितना अधिक मैं गया था, उतना अधिक प्रश्न मुझे पसंद था "क्या यह वास्तव में कुछ भी करेगा?"

उदाहरण के लिए, ऊपर वर्णित लूप के बाहर एक चर को घोषित करने के बजाय और सिर्फ लूप में उसका मान सेट करना … उन्होंने ऑब्जेक्ट को लूप में बनाया। मेरा कहने का तात्पर्य है:

for(int i=0; i < arrayOfStuff.size(); i++) { String something = (String) arrayOfStuff.get(i); ... } 

बनाम

 String something = null; for(int i=0; i < arrayOfStuff.size(); i++) { something = (String) arrayOfStuff.get(i); } 

क्या मुझे यह कहना गलत है कि नीचे की लूप बेहतर है? शायद मैं गलत हूँ

इसके अलावा, ऊपर के दूसरे लूप के बारे में क्या, मैं "कुछ" वापस रिक्त करने के लिए सेट? क्या यह कुछ मेमोरी साफ करेगा?

या तो किसी भी मामले में, कुछ अच्छा मेमोरी प्रबंधन क्या सर्वोत्तम प्रथाओं का पालन कर सकता है जो कि मेरे अनुप्रयोगों में मेरी मेमोरी उपयोग को कम रखने में मदद करेगा?

अद्यतन करें:

मैं अब तक सभी फीडबैक की सराहना करता हूं। हालांकि, मैं वास्तव में उपरोक्त छोरों के बारे में नहीं पूछ रहा था (हालांकि आपकी सलाह के अनुसार मैंने पहले लूप पर वापस जाना था)। मैं कुछ बेहतरीन प्रथाओं को प्राप्त करने की कोशिश कर रहा हूं जिनके लिए मैं आँख रख सकता हूं। "जब आप किसी कलेक्शन का उपयोग करके किया जाता है, तो उसे साफ़ करें" की तर्ज पर कुछ। मुझे वास्तव में यह सुनिश्चित करने की ज़रूरत है कि इन एप्लिकेशनों द्वारा जितनी ज्यादा मेमोरी नहीं की जा रही है

Solutions Collecting From Web of "कुछ जावा मेमोरी प्रबंधन सर्वोत्तम अभ्यास क्या हैं?"

वीएम को चौंका देने की कोशिश मत करो प्रदर्शन और रखरखाव दोनों के लिए पहला लूप सुझाव दिया गया सर्वोत्तम अभ्यास है। लूप के संदर्भ को वापस रिक्त करने के लिए तत्काल मेमोरी रिहाई की गारंटी नहीं दी जाएगी। जब आप न्यूनतम संभव अवसर का उपयोग करते हैं तो जीसी अपनी नौकरी सबसे अच्छा करेगी।

पुस्तकें जो इन चीजों को विस्तार से बताती हैं (उपयोगकर्ता के नजरिए से) प्रभावी जावा 2 और कार्यान्वयन पैटर्न हैं ।

यदि आप वीएम के निष्पादन और शुरुआत के बारे में अधिक जानकारी प्राप्त करते हैं, तो आपको वार्ता देखने या ब्रायन गेटज़ से पुस्तकों को पढ़ने की आवश्यकता है।

उन दो छोरों को something के दायरे को छोड़कर समकक्ष हैं; विवरण के लिए यह प्रश्न देखें।

सामान्य सर्वोत्तम प्रथाएं? उम्म, चलिए देखते हैं: स्थिर चर में डेटा की बड़ी मात्रा में स्टोर न करें जब तक आपके पास कोई अच्छा कारण न हो। संग्रह से बड़े ऑब्जेक्ट निकालें जब आप उनके साथ कर लेंगे। और ओह हाँ, "उपाय, अनुमान न करें।" यह देखने के लिए कि स्मृति को आवंटित किया जा रहा है, एक प्रोफ़ाइलर का उपयोग करें।

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

दो लूप मूल रूप से स्मृति की समान मात्रा का उपयोग करेंगे, कोई भी अंतर नगण्य होगा। "स्ट्रिंग कुछ" केवल एक ऑब्जेक्ट का संदर्भ बनाता है, न कि एक नई ऑब्जेक्ट अपने आप में और इस प्रकार कोई अतिरिक्त मेमोरी छोटा है। इसके अलावा, कंपाइलर / संयुक्त जेवीएम के साथ संयुक्त रूप से उत्पन्न कोड को वैसे भी अनुकूलन होगा।

स्मृति प्रबंधन प्रथाओं के लिए, आपको वास्तव में अपनी याददाश्त को बेहतर ढंग से प्रोफाइल करने की कोशिश करनी चाहिए ताकि ये समझ सकें कि बाधाओं को वास्तव में कहां है। विशेष रूप से स्थिर संदर्भों के लिए देखें, जो स्मृति के एक बड़े हिस्से को इंगित करते हैं, क्योंकि कभी भी एकत्र नहीं किया जाएगा

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

अंत में, ध्यान रखें कि यदि कोई एप्लिकेशन स्मृति को लेता है, तो इसके लिए एक कारण हो सकता है ….

अपडेट मेमोरी प्रबंधन की कुंजी है डेटा संरचनाएं, साथ ही साथ आपको कितनी कार्यक्षमता की आवश्यकता है / जब। ट्रेंडऑफ़ अक्सर स्मृति और CPU चक्र के बीच होता है

उदाहरण के लिए, कैशिंग द्वारा बहुत सारी मेमोरी पर कब्जा कर लिया जा सकता है, जो कि विशेष रूप से प्रदर्शन को सुधारने के लिए है क्योंकि आप महंगे ऑपरेशन से बचने की कोशिश कर रहे हैं।

तो अपने डेटा संरचनाओं के माध्यम से सोचें और सुनिश्चित करें कि आप चीजों को आपके स्मृति से अधिक समय तक नहीं रखते हैं। यदि यह एक वेब ऐप है, तो सत्र के चर में बहुत सारे डेटा संग्रहीत करने से बचें, मेमोरी के विशाल पूल के स्थैतिक संदर्भों से बचें।

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

आखिरकार, # 1 चीज़ को आप से बचना चाहिए: अंतिम उपयोगकर्ताओं का उपयोग कभी नहीं करना अंतिम वस्तुएं कचरा संग्रह में हस्तक्षेप करती हैं, क्योंकि वस्तु को सिर्फ मुक्त नहीं किया जा सकता है, लेकिन अंतिम रूप देने के लिए कतारबद्ध होना चाहिए, जो हो सकता है या नहीं भी हो सकता है। फ़ाइनलर्स का उपयोग कभी नहीं करना सबसे अच्छा है

स्मृति उपयोग के लिए आप एक्लिप्स में देख रहे हैं, यह जरूरी प्रासंगिक नहीं है जीसी अपनी नौकरी पर निर्भर करता है कि वहां कितनी नि: शुल्क मेमोरी है। अगर आपके पास बहुत सारी मुफ्त मेमोरी है तो आपको ऐप बंद होने से पहले एक जीसी नहीं दिखाई देगी। यदि आप अपना ऐप मेमोरी से बाहर चल रहे हैं तो केवल एक वास्तविक प्रोफ़ाइलर आपको बता सकता है कि लीक या अक्षमता कहां है।

पहला लूप बेहतर है इसलिये

  • चर कुछ तेजी से साफ हो जाएगा (सैद्धांतिक)
  • कार्यक्रम पढ़ने के लिए बेहतर है

लेकिन स्मृति के बिंदु से यह अप्रासंगिक है।

यदि आपके पास मेमोरी समस्याएं हैं तो आपको प्रोफ़ाइल चाहिए जहां यह खपत होती है।

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

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

डेटा संरचनाओं तक पहुंचने के लिए उचित एल्गोरिदम का उपयोग करें। निम्नतम स्तर पर, जैसा कि आपने उल्लिखित लूप का प्रयोग किया है, Iterator उपयोग करें या कम से कम समय बिताने से बचें। (हां, आप हर बार इस सूची के आकार के लिए पूछ रहे हैं, जो कि ज्यादातर समय में परिवर्तन नहीं होता है।) बीटीडब्लू, मैंने अक्सर Map साथ इसी तरह की गलती देखी है। लोगों को पहली जगह में entrySet() पर प्रवेश करने की बजाए keySet() पर पुनरावृत्त करें और प्रत्येक मान get । मेमोरी मैनेजर आपको अतिरिक्त सीपीयू चक्रों के लिए धन्यवाद देंगे।

सुझाव दिए गए ऊपर एक पोस्टर के रूप में, अपने कार्यक्रम के कुछ हिस्सों की मेमोरी (और / या सीपीयू) उपयोग को मापने के लिए प्रोफाइलर का उपयोग करने के बजाय इसका अनुमान लगाने का उपयोग करें जो आप पाएंगे उस पर आप आश्चर्यचकित भी हो सकते हैं!

उस रूप में भी एक अतिरिक्त लाभ है आप अपनी प्रोग्रामिंग भाषा और आपके आवेदन के बारे में और अधिक समझेंगे।

मैं विज़ुअलाइजिंग प्रोफाइल के लिए प्रयोग कर रहा हूं और इसे बहुत सराहनीय करता हूं। यह jdk / jre वितरण के साथ आता है

ठीक है, पहली लूप वास्तव में बेहतर है, क्योंकि कुछ का दायरा छोटा है स्मृति प्रबंधन के संबंध में – यह एक बड़ा अंतर नहीं बनाता है

अधिकांश मेमोरी समस्याएं आती हैं जब आप ऑब्जेक्ट्स संग्रह में संग्रहीत करते हैं, लेकिन उन्हें निकालना भूल जाते हैं। अन्यथा जीसी अपनी नौकरी काफी अच्छा बनाती है।

पहला उदाहरण ठीक है। प्रत्येक समय लूप के माध्यम से (बहुत सस्ता और तेज़) एक स्टैक चर आवंटन और डेलोकेशन के अलावा कोई स्मृति आवंटन वहां पर नहीं चल रहा है।

इसका कारण यह है कि सभी 'आबंटित' किया जा रहा है एक संदर्भ है, जो एक 4 बाइट स्टैक वैरिएबल है (वैसे भी 32 बिट सिस्टम पर) एक स्टैक वैरिएबल 'आवंटित' है जो स्टैक्स के ऊपर का प्रतिनिधित्व करने वाला मेमोरी एड्रेस जोड़ता है, और ऐसा बहुत तेज और सस्ते है।

आपको सावधानी बरतने की ज़रूरत है जैसे छोरों के लिए:

 for (int i = 0; i < some_large_num; i++) { String something = new String(); //do stuff with something } 

जैसा कि वास्तव में मेमोरी आवंटित कर रहा है

यदि आपके पास पहले से ही नहीं है, तो मैं सुझाव देता हूं कि एक्लिपस टेस्ट एंड परफॉर्मेंस टूल प्लेटफॉर्म (टीपीटीपी) को स्थापित करना है। यदि आप ढेर को डंप और निरीक्षण करना चाहते हैं, तो एसडीके जेएमएपी और जेट टूल्स देखें। साथ ही जावा SE 6 प्लेटफ़ॉर्म अनुप्रयोगों की निगरानी और प्रबंध देखें।

"क्या मैं यह कहने में गलत हूं कि नीचे की लूप बेहतर है?", इसका उत्तर नहीं है, न केवल बेहतर है, वही मामला आवश्यक है … चर परिभाषा (सामग्री नहीं), मेमोरी ढेर में बनाई गई है, और है पहले उदाहरण में, प्रत्येक लूप इस मेमोरी में एक उदाहरण बनाते हैं, और यदि "arrayOfStuff" का आकार बड़ा है, तो "मेमोरी त्रुटि से बाहर: जावा हीप स्पेस" हो सकता है ….

मैं जो समझता हूं, आप देख रहे हैं, नीचे की लूप बेहतर नहीं है इसका कारण यह भी है कि यदि आप एक संदर्भ (पूर्व- कुछ) का पुन: उपयोग करने की कोशिश कर रहे हैं, तो यह तथ्य वस्तु (Ex-arrayOfStuff.get (i)) अभी भी सूची (सरणी ऑफ़स्टफ) से संदर्भित किया जा रहा है। वस्तुओं को संग्रह के लिए पात्र बनाने के लिए, उन्हें किसी भी स्थान से संदर्भित नहीं किया जाना चाहिए। यदि आप इस बिंदु के बाद सूची के जीवन के बारे में सुनिश्चित हैं, तो आप अलग-अलग पाश के भीतर वस्तुओं को हटाने / मुक्त करने का निर्णय ले सकते हैं।

ऑप्टिमाइज़ेशन जो एक स्थिर परिप्रेक्ष्य से किया जा सकता है (यानी किसी भी अन्य धागा से इस सूची में कोई संशोधन नहीं हो रहा है), आकार () बार-बार बोलने से बचने के लिए बेहतर है ऐसा तब है जब आप आकार बदलने की उम्मीद नहीं कर रहे हैं, तो फिर इसे बार-बार क्यों गणना करना चाहिए; आखिर यह सरणी नहीं है। लम्बाई, यह list.size है ()।