2010-01-07 20 views
6

मैं अपने आवेदन के भीतर कुछ मेमोरी लीक से छुटकारा पाने के तरीकों से प्रयोग कर रहा था, दूसरे दिन जब मुझे एहसास हुआ कि मुझे अपने संसाधनों को साफ करने के बारे में कुछ भी नहीं पता है। मैंने कुछ शोध किया, और उम्मीद की कि बस .isis() को बुलाकर मेरी सभी समस्याओं का समाधान होगा। हमारे पास हमारे डेटाबेस में एक टेबल है जिसमें लगभग 65,000 रिकॉर्ड हैं। जाहिर है जब मैं डेटा एडाप्टर से अपना डेटासेट भरता हूं, तो स्मृति उपयोग बहुत अधिक हो सकता है। जब मैंने डेटासेट पर निपटान विधि बुलाई, तो मुझे यह जानकर आश्चर्य हुआ कि स्मृति में से कोई भी रिलीज़ नहीं हुआ। ऐसा क्यों हुआ? डेटासेट साफ़ करना या तो मदद नहीं करता है।क्या डिस्प्ले() विधि कुछ भी करती है?

उत्तर

25

IDisposable और इस प्रकार Dispose स्मृति दबाव को कम करने के लिए उपयोग नहीं किया जाता है, हालांकि कुछ मामलों में यह हो सकता है, लेकिन इसके बजाय निर्धारक सफाई के लिए उपयोग किया जा सकता है।

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

आप निश्चित रूप से वस्तु को तब छोड़ सकते हैं जब आप इसके साथ काम करते हैं, और आखिरकार इसे कचरा कलेक्टर द्वारा उठाया जाएगा, लेकिन मान लीजिए कि आप यह सुनिश्चित करना चाहते हैं कि कम से कम संसाधन मुक्त हो जाएं, और इस प्रकार कनेक्शन बंद हो गया, जब आप इसके साथ कर रहे हैं। यह वह जगह है जहां IDisposable है। Dispose खेल में आता है।

इसका उपयोग ऑब्जेक्ट द्वारा प्रबंधित संसाधनों को साफ़ करने के लिए किया जाता है।

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

क्या आपको वास्तव में एक स्मृति समस्या है, या आप बस कार्य प्रबंधक या इसी तरह के स्मृति उपयोग को देखते हैं और "यह थोड़ा अधिक है"।

यदि बाद वाला, तो आपको इसे अभी छोड़ना चाहिए। यदि आपके पास कम मेमोरी उपलब्ध है, तो .NET कचरा संग्रह अधिक बार चलाएगा, इसलिए जब तक आप ऐसी स्थिति में न हों जहां आपको मिलता है, या आपको संदेह हो सकता है कि आप जल्द ही मिल जाएंगे, एक मेमोरी ओवरफ्लो हालत, आपको शायद कोई समस्या नहीं होगी ।

मुझे बताएं कि "कम बार चलाने" से मेरा क्या मतलब है।

यदि आपके मशीन में 8 जीबी मेमोरी है, और केवल विंडोज और नोटपैड चल रहा है, तो अधिकांश मेमोरी उपलब्ध होगी। जब आप अब अपना प्रोग्राम चलाते हैं, भले ही यह स्मृति में मामूली डेटा ब्लॉक लोड करता है, आप इसे लंबे समय तक कर सकते हैं, और स्मृति उपयोग लगातार बढ़ेगा। वास्तव में जब जीसी किक करेगा और आपकी मेमोरी पदचिह्न को कम करने का प्रयास करेगा, मुझे नहीं पता, लेकिन मैं आपको लगभग गारंटी दे सकता हूं कि आपको आश्चर्य होगा कि यह इतना ऊंचा क्यों हो जाता है।

चलिए सिर्फ तर्क के लिए कहते हैं कि आपका प्रोग्राम अंततः 2 जीबी मेमोरी का उपयोग करेगा।

अब, यदि आप अपने प्रोग्राम को उस मशीन पर चलाते हैं जिसमें कम मेमोरी उपलब्ध है, तो जीसी अधिक बार होता है, और कम सीमा पर लात मारता है, जो स्मृति उपयोग को 500 एमबी से कम या संभवतः कम भी रख सकता है।

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

+0

मेरा प्रोग्राम 700,164k तक पहुंच सकता है। मेरे ग्राहकों पर कम अंत कंप्यूटर होने पर विचार करने में अच्छा नहीं है। – broke

+6

जिसका अर्थ है कि आपने मेरा जवाब नहीं पढ़ा है। कई बड़े अनुप्रयोगों को लोड करने का प्रयास करें ताकि आप अपना प्रोग्राम शुरू करने से पहले, आपके पास 700,164k मेमोरी उपलब्ध हो (वर्चुअल मेमोरी समेत)। फिर इसे लोड करने का प्रयास करें, यह संभवतः तब भी काम करेगा जब तक कि आप उपयोग के लिए स्मृति में डेटा से अधिक लोड नहीं कर रहे हैं, इस मामले में जीसी बिल्कुल मदद नहीं करेगा, आपको बस उस प्रक्रिया की मात्रा को कम करने की आवश्यकता है जो आप संसाधित करते हैं किसी भी समय। –

+0

ठीक है बीमार इसे आज़माएं। – broke

4

कॉलिंग निपटान() केवल फाइल हैंडल, डेटाबेस कनेक्शन, अप्रबंधित स्मृति इत्यादि जैसे अप्रबंधित संसाधनों को छोड़ देगा। यह नहीं कचरा एकत्रित स्मृति जारी करेगा।

कचरा एकत्रित स्मृति केवल अगले संग्रह में रिलीज़ हो जाएगी। आमतौर पर जब एप्लिकेशन डोमेन मेमोरी पूर्ण हो जाती है।

3

मैं यहां कुछ ऐसा इंगित करने जा रहा हूं जिसका स्पष्ट रूप से उल्लेख नहीं किया गया है: Dispose() कॉलिंग केवल घटक (मुक्त) अप्रबंधित संसाधनों को साफ़ कर देगा यदि घटक के डेवलपर ने इसे कोड किया है।

क्या मेरा मतलब यह है: बुला Dispose() ठीक करने के लिए नहीं जा रहा है अगर आपको संदेह है कि आप एक स्मृति रिसाव है, यह मूल निर्माता एक घटिया काम किया है और सही ढंग से अप्रबंधित संसाधनों को मुक्त कर दिया नहीं तो। थोड़ी अधिक जानकारी के लिए, check this blog post। बयान पर ध्यान दें व्यवहार का व्यवहार डेवलपर द्वारा परिभाषित किया गया है।

1

कुछ ऑब्जेक्ट्स अन्य संस्थाओं के नुकसान के लिए आगे की सूचना तक एक या अधिक अन्य संस्थाओं से इसकी ओर से कुछ करने के लिए कहेंगे। यदि ऐसी वस्तुएं जो पूर्व संस्थाओं को सूचित किए बिना गायब हो गईं कि उनकी सेवाओं की अब आवश्यकता नहीं थी, तो वे संस्थाएं उन वस्तुओं की ओर से कार्य करने के लिए जारी रहेंगी जिन्हें अब उनकी आवश्यकता नहीं है, अन्य संस्थाओं के निरंतर नुकसान के लिए जो उन्हें चाहिए उनका उपयोग करने के लिए।

कई मामलों में, "जॉर्ज" किसी बाहरी इकाई को "जो" कहने के लिए कहा जाता है कि इसकी सेवाओं की अब आवश्यकता नहीं थी, जॉर्ज को यह जानना होगा कि इसकी सेवाओं की आवश्यकता नहीं थी। दो सामान्य माध्यम हैं जिसके माध्यम से .NET, अंतिमकरण और IDIsposable में हो सकता है।

यदि कोई ऑब्जेक्ट Finalize नामक विधि को ओवरराइड करता है, तो जब ऑब्जेक्ट बनाया जाता है तो .NET कचरा कलेक्टर इसे पंजीकृत फ़ाइनलाइज़र वाले ऑब्जेक्ट्स की सूची में जोड़ देगा। यदि जीसी पता चलता है कि उस सूची के अलावा अन्य वस्तु के लिए कोई जड़ संदर्भ नहीं है, तो जीसी उस सूची से ऑब्जेक्ट को हटा देगा और इसे ऑब्जेक्ट्स की दृढ़ता से जड़ वाली कतार में जोड़ देगा, जिसमें जितनी जल्दी हो सके Finalize विधि होनी चाहिए। इस तरह की एक वस्तु तब अन्य 0 इकाइयों को सूचित करने के लिए Finalize विधि का उपयोग कर सकती है, जिनकी सेवाओं की अब आवश्यकता नहीं है।

हालांकि अंतिम रूप से आधारित सफाई कभी-कभी काम कर सकती है, समयबद्धता की कोई गारंटी नहीं है। माइक्रोसॉफ्ट के डिजाइन के दौरान एक बिंदु पर माइक्रोसॉफ्ट का इरादा हो सकता है कि अंतिमकरण प्राथमिक सफाई विधि होगी, लेकिन कई कारणों से इसे सुरक्षित रूप से भरोसा नहीं किया जा सकता है।

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

ध्यान दें कि IDisposable.Dispose आम तौर पर वादा करता है कि किसी भी बाहरी संस्थाओं को किसी ऑब्जेक्ट की ओर से कुछ करने के लिए कहा गया था, उन्हें बताया जाएगा कि उन्हें अब ऐसा करने की आवश्यकता नहीं है, लेकिन ऐसा वादा यह नहीं दर्शाता है कि इकाइयों की संख्या गैर नहीं है शून्य। अगर किसी ऑब्जेक्ट ने किसी बाहरी संस्था से अपनी तरफ से कुछ भी करने के लिए नहीं कहा है, तो "सभी" ऐसी संस्थाओं को एक संदेश देने के लिए कुछ भी करने की आवश्यकता नहीं है।दूसरी तरफ, तथ्य यह है कि Dispose विधि कुछ मामलों में कुछ भी नहीं कर सकती है इसका मतलब यह नहीं है कि किसी भी मामले में कभी भी कुछ भी करने की गारंटी नहीं है, न ही उन मामलों में इसे कॉल करने में विफलता जहां यह कुछ नहीं करेगा हानिकारक प्रभाव।

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