.NET

2011-03-09 5 views
42

में स्मृति विखंडन का कारण बनता है मैं एक स्मृति रिसाव डीबग करने के लिए लाल गेट्स एएनटीएस मेमोरी प्रोफाइलर का उपयोग कर रहा हूं। यह मुझे चेतावनी रहता है कि:.NET

मेमोरी विखंडन नेट बहुत अधिक मुक्त स्मृति संचयकर्ता के कारण हो सकता है।

या

मेमोरी विखंडन सबसे बड़ा उद्देश्य यह है कि

क्योंकि मैं ओसीडी है आवंटित किया जा सकता है के आकार को प्रभावित कर रहा है, इस समस्या का समाधान किया जाना चाहिए।

कुछ मानक कोडिंग प्रथाएं क्या हैं जो स्मृति विखंडन से बचने में मदद करती हैं। क्या आप इसे कुछ .NET तरीकों से डिफ्रैगमेंट कर सकते हैं? क्या यह भी मदद करेगा?

+6

में अधिक जानकारी देखें यह इस है एप्लिकेशन किस तरह के बारे में कुछ जानकारी है मदद मिलेगी। मेमोरी विखंडन तब होगा जब आप मेमोरी पिन कर रहे हैं (या I/O फ़ंक्शंस का उपयोग करते हुए जो दृश्यों के पीछे I/O बफर पिन करते हैं), मूल आवंटकों (जैसे COM कार्य आवंटक) से आवंटन, या बहुत सारी बड़ी वस्तुएं बनाते हैं, क्योंकि LOH संकुचित नहीं होता है। .NET कचरा कलेक्टर पहले से ही पीढ़ी के गतिशील आवंटन को कॉम्पैक्ट करता है, जिसका मुक्त स्थान डीफ्रैगमेंटिंग का दुष्प्रभाव होता है। यदि ऐसा नहीं हो रहा है, तो ऐसा इसलिए है क्योंकि कुछ वस्तुओं को स्थानांतरित होने से रोक रहा है। –

+28

* क्योंकि मेरे पास ओसीडी है, इस समस्या को हल किया जाना चाहिए। * + 1 इस टिप्पणी के लिए अकेले - मुझे वास्तव में प्रश्न पसंद है हालांकि – BrokenGlass

+9

अनइंस्टॉल करने वाले टूल जो आपको कुचलना चाहते हैं लेकिन समस्या का निदान करने में कोई सहायता नहीं देते हैं।मेमोरी विखंडन जीवन का एक तथ्य है, ऐसा कुछ भी नहीं है जिसे आप इसे रोकने के लिए कर सकते हैं जो बहुत ही अप्रत्याशित नहीं होगा। कम विखंडन हीप आवंटक Vista और ऊपर के लिए पहले से ही डिफ़ॉल्ट है। यह केवल एक समस्या है यदि आप उपलब्ध पता स्थान के आधे से अधिक आवंटित करते हैं, तो सूअर उड़ते नहीं हैं। –

उत्तर

9

आप जानते हैं, मुझे कुछ हद तक मेमोरी प्रोफाइलर पर संदेह है। .NET में मेमोरी मैनेजमेंट सिस्टम वास्तव में स्मृति के चारों ओर घूमकर आपके लिए ढेर को डिफ्रैगमेंट करने का प्रयास करता है (यही कारण है कि आपको बाहरी DLL के साथ साझा करने के लिए स्मृति पिन करने की आवश्यकता है)।

लंबे समय तक ली गई बड़ी मेमोरी आवंटन अधिक विखंडन के लिए प्रवण है। जबकि छोटे क्षणिक (लघु) स्मृति अनुरोध .NET में विखंडन का कारण बनने की संभावना नहीं है।

यहां कुछ भी सोचने योग्य है। .NET के वर्तमान जीसी के साथ, समय में बंद आवंटित स्मृति, आमतौर पर अंतरिक्ष में एक साथ घिरा हुआ है। जो विखंडन के विपरीत है। यानी आपको स्मृति को आवंटित करना चाहिए जिस तरह से आप इसका उपयोग करना चाहते हैं।

क्या यह केवल एक प्रबंधित कोड है या इसमें पी/इनवोक, अप्रबंधित स्मृति (मार्शल.एलोक एचजीएलओबल) या GCHandle.Alloc (obj, GCHandleType.Pinned) जैसी चीजें शामिल हैं?

+6

जीसी बड़े ऑब्जेक्ट ढेर को कॉम्पैक्ट नहीं करता है, जहां ऑब्जेक्ट्स> 85 केबी रहते हैं। एक बार LOH खंडित हो जाने पर, इसे डिफ्रैगमेंट करने का कोई तरीका नहीं है। –

+0

.NET 4.5.1m के रूप में LOH मैन्युअल रूप से कॉम्पैक्ट करने का एक तरीका है, हालांकि मैं इसके कारण दृढ़ता से अनुशंसा करता हूं कि यह आपके ऐप के लिए एक बड़ा प्रदर्शन हिट है। https://blogs.msdn.microsoft.com/mariohewardt/2013/06/26/no-more-memory-fragmentation-on-the-net-large-object-heap/ (फिर से, मैं इसके खिलाफ अनुशंसा करता हूं) –

10

जीसी ढेर बड़े ऑब्जेक्ट आवंटन का अलग-अलग व्यवहार करता है। यह उन्हें कॉम्पैक्ट नहीं करता है, बल्कि इसके बजाय आसन्न मुक्त ब्लॉक (पारंपरिक अप्रबंधित मेमोरी स्टोर की तरह) को जोड़ता है।

अधिक यहाँ जानकारी: http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

तो बहुत बड़ी वस्तुओं के साथ सबसे अच्छी रणनीति के लिए उन्हें एक बार आवंटित और फिर उन पर पकड़ और उन्हें पुन: उपयोग किया जा सके।

+1

आउट जिज्ञासा के बारे में, मुझे आश्चर्य है कि LOH ऑब्जेक्ट आकार 4096 के अगले एकाधिक तक क्यों नहीं हैं? ऐसा लगता है कि कुछ ओएस संदर्भों में कॉम्पैक्शन की सुविधा होगी (स्मृति को कॉपी करने के बजाय वर्चुअल पेज पॉइंटर्स को ले जाएं), और विखंडन को भी बहुत कम कर देगा। चूंकि LOH ऑब्जेक्ट्स आमतौर पर कम से कम 85K होते हैं, 4K ब्लॉक तक गोल करने से ऊपर की ओर 5% या उससे कम होगा। – supercat

6

.NET Framework 4.5.1 में कचरा संग्रह के दौरान बड़े ऑब्जेक्ट हीप (LOH) को स्पष्ट रूप से कॉम्पैक्ट करने की क्षमता है।

GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; 
GC.Collect(); 

GCSettings.LargeObjectHeapCompactionMode

+0

मैं इस कारण के लिए दृढ़ता से अनुशंसा करता हूं कि यह आपके ऐप के लिए 2 कारणों से एक बड़ा प्रदर्शन हिट है: 1. यह समय 2 उपभोग कर रहा है 2. यह आवंटन पैटर्न एल्गोरिदम में से किसी एक को साफ़ करता है जिसे जीसी ने एकत्र किया है आपके ऐप का जीवनकाल जबकि आपका ऐप चल रहा है, जीसी वास्तव में यह सीखकर खुद को ट्यून करता है कि आपका ऐप मेमोरी आवंटित करता है। इस प्रकार, यह अधिक कुशल हो जाता है (एक निश्चित बिंदु पर) जितना लंबा आपका ऐप चलता है। जब आप जीसी। कोलेक्ट() (या इसके किसी भी ओवरलोड) को निष्पादित करते हैं, तो यह जीसी के सभी डेटा को साफ़ करता है - इसलिए इसे शुरू करना होगा। –

+0

@ डेव ब्लैक, जहां आपको ऐसी जानकारी मिली? एमएसडीएन में आवंटन पैटर्न एल्गोरिदम पर एलओएच कॉम्पैक्टिंग के प्रभाव के बारे में जानकारी नहीं है। – 23W

+1

@ 23W, मैं उन लोगों को जानता हूं जो टीम पर काम करते हैं। –

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