दिलचस्प पोस्ट
जावास्क्रिप्ट में Java / Servlet / JSP / JSTL / EL चर का उपयोग करें आप स्ट्रिंग से गैर- ASCII वर्ण कैसे पट्टी कर सकते हैं? (सी # में) Matlotlib में बार चार्ट्स के लिए समूह लेबल कैसे जोड़ें? सादे जावास्क्रिप्ट का उपयोग करके वर्णों को HTML एंटिटी में परिवर्तित करने के लिए ListBoxItem के अंदर जटिल UI जावा में नियमित अभिव्यक्ति के लिए टेक्स्ट से कैसे बचें Python 2.7.3 के साथ 64 बिट विंडोज 7 पर नुकीले स्थापित तत्व को किसी अन्य तत्व में कैसे स्थानांतरित करना है? Android में पिक्सेल रंग कैसे प्राप्त करें? एकाधिक जीआईटी वापस आना क्या किसी को ड्रैग एंड ड्रॉप, पुन: क्रम-योग्य सूची के निम्न स्तर (कोई फ्रेमवर्क) का पता नहीं है? PHP, MySQL त्रुटि: स्तंभ गिनती पंक्ति 1 पर मान गणना से मेल नहीं खाती मैं WebClient में 2 कनेक्शन सीमा को प्रोग्रामेटिक रूप से कैसे हटा सकता / सकती हूं? MySQL जहां क्लॉज के साथ जुड़ें एक नकारात्मक बदलाव संख्या के साथ वाम स्थानांतरण

बड़े ऑब्जेक्ट हीप फ्रेग्मेंटेशन

सी # /। NET आवेदन मैं पर काम कर रहा हूँ धीमी स्मृति रिसाव से पीड़ित है। मैंने सीओडी के साथ एसओएस का प्रयोग किया है जो यह तय करने के लिए किया जा रहा है कि क्या हो रहा है लेकिन डेटा किसी भी समझ में नहीं आता है, इसलिए मैं उम्मीद कर रहा था कि आप में से एक यह अनुभव पहले हो सकता है।

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

0:000> !DumpHeap 000000005b5b1000 000000006351da10 Address MT Size ... 000000005d4f92e0 0000064280c7c970 16147872 000000005e45f880 00000000001661d0 1901752 Free 000000005e62fd38 00000642788d8ba8 1056 <-- 000000005e630158 00000000001661d0 5988848 Free 000000005ebe6348 00000642788d8ba8 1056 000000005ebe6768 00000000001661d0 6481336 Free 000000005f214d20 00000642788d8ba8 1056 000000005f215140 00000000001661d0 7346016 Free 000000005f9168a0 00000642788d8ba8 1056 000000005f916cc0 00000000001661d0 7611648 Free 00000000600591c0 00000642788d8ba8 1056 00000000600595e0 00000000001661d0 264808 Free ... 

जाहिर है मैं यह उम्मीद करता हूं कि यदि मेरा आवेदन हर गणना के दौरान दीर्घकालिक, बड़े ऑब्जेक्ट्स बना रहा हो। (यह ऐसा करता है और मैं स्वीकार करता हूं कि वहाँ एक लोहे के विखंडन की डिग्री होगी लेकिन यह यहां समस्या नहीं है।) समस्या बहुत कम (1056 बाइट) ऑब्जेक्ट सरणियां हैं जो आप उपरोक्त डंप में देख सकते हैं जो मुझे कोड में नहीं दिखाई दे सकती बनाया जा रहा है और जो किसी भी तरह निहित शेष हैं

यह भी ध्यान रखें कि जब सीडीबी उस प्रकार की रिपोर्ट नहीं कर रहा है जब हेप सेगमेंट को डंप किया जाता है: मुझे यकीन नहीं है कि यह संबंधित है या नहीं। यदि मैं चिह्नित (<-) ऑब्जेक्ट को डंप करता हूं, तो सीडीबी / एसओएस इसे ठीक बताता है:

 0:015> !DumpObj 000000005e62fd38 Name: System.Object[] MethodTable: 00000642788d8ba8 EEClass: 00000642789d7660 Size: 1056(0x420) bytes Array: Rank 1, Number of elements 128, Type CLASS Element Type: System.Object Fields: None 

ऑब्जेक्ट सरणी के तत्व सभी स्ट्रिंग हैं और स्ट्रिंग हमारे एप्लिकेशन कोड से पहचानने योग्य हैं।

इसके अलावा, मैं अपनी जीसी की जड़ों को खोजने में असमर्थ हूं! जीसीआरयूटीसीटी कमांड लटकी हुई है और कभी भी वापस नहीं आ रहा है (मैंने इसे रातोंरात छोड़ने का भी प्रयास किया है)।

इसलिए, मैं इसकी सराहना करता हूं कि कोई भी कोई प्रकाश क्यों छोड़ सकता है, क्यों कि इन छोटे (<85 के) ऑब्जेक्ट एआरएम्स को LOH पर समाप्त हो रहा है: क्या परिस्थितियों में .NET ने एक छोटी ऑब्जेक्ट सरणी रखी? इसके अलावा, क्या किसी को भी इन वस्तुओं की जड़ों का पता लगाने का एक वैकल्पिक तरीका पता है?


अपडेट 1

देर से कल के साथ आए एक अन्य सिद्धांत यह है कि ये ऑब्जेक्ट सरणियां बड़ी शुरूआत हुई हैं लेकिन स्मृति के ढंके में स्पष्ट रूप से मुक्त स्मृति के ब्लॉक को छोड़ने से सिकुड़ रहे हैं। मुझे क्या संदेहास्पद लगता है कि ऑब्जेक्ट एरे हमेशा 1056 बाइट्स लंबे (128 तत्व), संदर्भ के लिए 128 * 8 और ओवरहेड के 32 बाइट्स होते हैं।

विचार यह है कि शायद पुस्तकालय में या सीएलआर में कुछ असुरक्षित कोड सरणी शीर्ष लेख में तत्वों की संख्या को खराब कर रहा है। मुझे पता है कि एक लंबे शॉट के बिट …


अपडेट 2

ब्रायन रासमुसेन के लिए धन्यवाद (स्वीकार किए जाते हैं जवाब देखें) इस समस्या को स्ट्रिंग इन्टर टेबल के कारण LOH के विखंडन के रूप में पहचान की गई है! मैंने इसकी पुष्टि करने के लिए एक त्वरित परीक्षण आवेदन लिखा था:

 static void Main() { const int ITERATIONS = 100000; for (int index = 0; index < ITERATIONS; ++index) { string str = "NonInterned" + index; Console.Out.WriteLine(str); } Console.Out.WriteLine("Continue."); Console.In.ReadLine(); for (int index = 0; index < ITERATIONS; ++index) { string str = string.Intern("Interned" + index); Console.Out.WriteLine(str); } Console.Out.WriteLine("Continue?"); Console.In.ReadLine(); } 

एप्लिकेशन पहले एक लूप में अद्वितीय स्ट्रिंग्स बनाता है और डिरेफर करता है। यह सिर्फ यह साबित करने के लिए है कि स्मृति इस परिदृश्य में लीक नहीं करता है। जाहिर है यह नहीं होना चाहिए और यह नहीं है।

दूसरे लूप में, अनूठी स्ट्रिंग बनाई जाती हैं और इंटर्नल की जाती है। इस कार्रवाई की जड़ें उन्हें आंतरिक टेबल में क्या मुझे एहसास नहीं हुआ है कि इंटर्न तालिका का प्रतिनिधित्व कैसे किया जाता है ऐसा प्रतीत होता है कि इसमें पृष्ठों का एक सेट है – 128 स्ट्रिंग तत्वों के ऑब्जेक्ट सरणियों – जो LOH में बनाए गए हैं। यह सीडीबी / एसओएस में अधिक स्पष्ट है:

 0:000> .loadby sos mscorwks 0:000> !EEHeap -gc Number of GC Heaps: 1 generation 0 starts at 0x00f7a9b0 generation 1 starts at 0x00e79c3c generation 2 starts at 0x00b21000 ephemeral segment allocation context: none segment begin allocated size 00b20000 00b21000 010029bc 0x004e19bc(5118396) Large object heap starts at 0x01b21000 segment begin allocated size 01b20000 01b21000 01b8ade0 0x00069de0(433632) Total Size 0x54b79c(5552028) ------------------------------ GC Heap Size 0x54b79c(5552028) 

LOH सेगमेंट के एक डंप लेते हुए मुझे लीकिंग एप्लीकेशन में देखा गया पैटर्न दिखाता है:

 0:000> !DumpHeap 01b21000 01b8ade0 ... 01b8a120 793040bc 528 01b8a330 00175e88 16 Free 01b8a340 793040bc 528 01b8a550 00175e88 16 Free 01b8a560 793040bc 528 01b8a770 00175e88 16 Free 01b8a780 793040bc 528 01b8a990 00175e88 16 Free 01b8a9a0 793040bc 528 01b8abb0 00175e88 16 Free 01b8abc0 793040bc 528 01b8add0 00175e88 16 Free total 1568 objects Statistics: MT Count TotalSize Class Name 00175e88 784 12544 Free 793040bc 784 421088 System.Object[] Total 1568 objects 

ध्यान दें कि ऑब्जेक्ट सरणी आकार 528 है (1056 के बजाय) क्योंकि मेरा वर्कस्टेशन 32 बिट है और एप्लीकेशन सर्वर 64 बिट है ऑब्जेक्ट सरणियां अब भी 128 तत्व लंबे हैं

तो इस कहानी के लिए नैतिक बहुत सावधान रहना होगा interning यदि आप जो स्ट्रिंग इंटर्निंग कर रहे हैं तो परिमित सेट का सदस्य नहीं माना जाता है, तो सीएलआर के संस्करण 2 में कम से कम LOH के विखंडन के कारण आपका आवेदन लीक होगा।

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

वेब के समाधान से एकत्रित समाधान "बड़े ऑब्जेक्ट हीप फ्रेग्मेंटेशन"

CLR कुछ ऑब्जेक्ट्स को प्रीलॉक करने के लिए LOH का उपयोग करता है (जैसे आंतरिक स्ट्रिंग के लिए इस्तेमाल किया गया सरणी ) इनमें से कुछ 85000 बाइट्स से कम हैं और इस प्रकार आम तौर पर LOH पर आवंटित नहीं किया जाएगा।

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

इसके अलावा कुछ विशिष्ट अनुकूल अनुकूलन के कारण, 1000 या अधिक तत्वों के किसी भी double[] LOH पर आवंटित किए जाते हैं।

माइक्रोसॉफ्ट हमें एक साधारण एपीआई के साथ क्यों नहीं प्रदान कर सकते हैं।

 GC.CompactLargeObjectHeap() 

भले ही इस पद्धति के कारण आवेदन 10 सेकंड या उससे ज्यादा के लिए लटकाए हो – यह क्रैशिंग से बाहर निकल जाता है और मेमोरी को साफ करने के लिए एप्लिकेशन को पुनरारंभ करने की आवश्यकता होती है!

ऐसे बहुत सारे अनुप्रयोग हैं जो 3 पार्टी लाइब्रेरीज़ का उपयोग करते हैं जो LOH पर आवंटन करते हैं। उदाहरण के लिए, यहां तक ​​कि माइक्रोसॉफ्ट के स्वयं के एक्सएएन ने हर बार जब आप "नया बनावट" ("बनावट") या "बनावट। फोमफाइल ()" को बिना किसी उपाय के लोहे से बाहर निकाला है!

इसलिए यदि आप .net में "गेम इंजन" बनाने का प्रयास कर रहे हैं – यह गर्दन में एक वास्तविक दर्द है, ताकि हमारे LOH को इसे रोकने के लिए बिना किसी भी तरह से स्मृति को रिसाव किया जा सके। हम जो कर सकते हैं वह "धीमा है", जब तक कि हम "अपनी लाइब्रेरी बनाने" का निर्णय न करें और XNA को भूल जाएं निश्चित रूप से यह नहीं है कि माइक्रोसॉफ्ट क्या चाहता है!

सिरदर्द के कई महीनों हमारे लिए हल किए जाएंगे (और अन्य!) यदि एमएस हमें इस विधि के साथ ही प्रदान करेगा; मैं इसे फिर से कहूंगा:

 GC.CompactLargeObjectHeap() 

और जब मैं यह सुझाव दे रहा हूं, तो मैं सुझाव दूँगा कि एमएस इसे एक कदम आगे बढ़ाएगा, और इस आदेश की अनुमति देगा:

 GC.DoLargeObjectHeapCompactionWhenOutOfMemory = true; // would be false by default 

इसलिए हम इसे "विजुअल 3 डी गेम इंजन" (हमारे उत्पाद) के लिए सही पर सेट कर देंगे, और तब स्वचालित रूप से, जब विखंडन को पहले ओ ओएम अपवाद का कारण बनता है, तो .NET स्वचालित रूप से LOH को कॉम्पैक्ट करेगा और फिर आवंटन का पुन: प्रयास करें!

वाह, अब यह ".Net प्रचार" के बारे में "यह काम करता है" और "उपयोग में आसान" के बारे में है … और केवल चरम मामलों के लिए यह "प्रदर्शन हिट" का कारण होगा, जहां वैकल्पिक ओओएम दुर्घटना है, फिर से शुरू करने के लिए मजबूर होना आवेदन की!

कृपया Microsoft – हमारे लिए ऐसा करें!


कृपया अपनी अज्ञानता की घोषणा न करें कि "बस बेहतर मेमोरी प्रबंधन का उपयोग करें" – यिश! यह बहुत अनुचित सलाह है! आपको यह भी कहना होगा कि "अपनी सभी तृतीय पक्षीय पुस्तकालयों को लिखें" (जैसे XNA) !!!!

माइक्रोसॉफ्ट ने पहले ही इस व्यवहार को नेट में क्यों नहीं दिया है ???? यह क्या चोट लगी होगी? यह हमें इन बेहद निराशाजनक और समय-उपभोक्ता बैंड-सहायता समाधानों से बचाएगा, जो सबसे अच्छा "स्मृति लीक को धीमा कर सकते हैं" लेकिन उन्हें पूरी तरह ठीक नहीं कर सकते हैं

हम जिस अनुरोध का अनुरोध कर रहे हैं, उन लोगों के लिए हानिकारक होगा जो इसका उपयोग नहीं करना चाहते हैं, और वास्तव में उन लोगों के लिए एक ताज़ा उद्धार प्रदान करते हैं जो वास्तव में इसका उपयोग करना चाहते हैं। कृपया, कृपया, कृपया इसे .NET 4.0+ में प्रदान करें।

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

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

GCSettings.LargeObjectHeapCompactionMode में अधिक जानकारी देखें

जीसी कैसे काम करता है और कैसे लंबे समय तक रहने वाली वस्तुओं का हिस्सा पीढ़ी 2 में समाप्त हो रहा है, और LOH ऑब्जेक्ट्स का संग्रह पूरी संग्रह में ही होता है, के विवरण को पढ़ते समय – जैसा कि पीढ़ी 2 का संग्रह होता है, यह विचार जो मन में प्रवाहित होता है .. क्यों न सिर्फ एक ही ढेर में 2 और बड़े ऑब्जेक्ट पीढ़े रखो, क्योंकि वे इकट्ठा हो रहे हैं एक साथ?

यदि वास्तव में ऐसा होता है तो यह समझाता है कि छोटी वस्तुओं को एक ही स्थान पर LOH के रूप में समाप्त हो जाता है – अगर वे लंबे समय तक पीढ़ी में खत्म करने के लिए पर्याप्त रहते हैं 2

और इसलिए आपकी समस्या मेरे विचार के लिए एक बहुत अच्छा खण्डन साबित होगी – इसका परिणाम LOH के विखंडन में होगा।

सारांश: आपकी समस्या LOH और पीढ़ी 2 द्वारा एक ही ढेर क्षेत्र साझा करके समझाया जा सकता है, हालांकि यह कोई सबूत नहीं है कि यह स्पष्टीकरण है।

अद्यतन: !dumpheap -stat का उत्पादन – पानी से बाहर इस सिद्धांत को बहुत ज्यादा वार करता है! पीढ़ी 2 और लोह्ह के अपने क्षेत्र हैं

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

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

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


संपादित करें: पल के लिए मेमोरी क्षेत्र और विशिष्ट सरणी आकार को अनदेखा करें: बस पता करें कि इन तारों के साथ क्या किया जा रहा है जिससे एक रिसाव पैदा हो सकता है। जब आपके प्रोग्राम ने इन स्ट्रिंग्स को एक बार या दो बार बनाया है या तब हेरफेर करने का प्रयास करें!

महान प्रश्न, मैंने प्रश्नों को पढ़ कर सीखा है

मुझे लगता है कि deserialisation कोड पथ के अन्य बिट भी बड़ी वस्तु ढेर का उपयोग कर रहे हैं, इसलिए विखंडन। यदि सभी तारों को उसी समय में बंद किया गया था, तो मुझे लगता है कि आप ठीक हो जाएंगे।

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

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

LOH आवंटन के सटीक कॉल-स्टैक को पहचानने के कई तरीके यहां दिए गए हैं।

और LOH विखंडन से बचने के लिए ऑब्जेक्ट के बड़े सरणी आवंटित करें और उन्हें पिन करें। जरूरत पड़ने पर इन वस्तुओं का पुन: उपयोग करें यहाँ LOH टुकड़े पर पोस्ट है । ऐसा कुछ LOH विखंडन से बचने में मदद कर सकता है

http://webcache.googleusercontent.com/search?q=cache:l3Ppy_eFoAAJ:www.wintellect.com/devcenter/sloscialo/hey-who-stole-all-my-memory+&cd=5&hl=hi&ct=clnk&gl= के अनुसार mx और ग्राहक = फ़ायरफ़ॉक्स-बी

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