2015-03-04 11 views
8

कुछ तथ्य: हमने डब्ल्यूसीएफ सेवा विकसित की है जो ग्राहकों और डेटाबेस के बीच एक परत के रूप में कार्य करता है। यह स्वस्थ है और विंडोज सेवा के रूप में चलता है।.NET Garbagecollector परेशानी। 15-40 मिनट के लिए ब्लॉक

सेवा कई कैश रखती है, जहां सबसे बड़ी स्मृति में 1-2 जीबी है। कुल स्मृति उपयोग आमतौर पर लगभग 5-8 जीबी होता है। कनेक्शन डुप्लेक्स हैं और टीसीपी प्रोटोकॉल का उपयोग करते हैं और serialization protobuf-net के साथ बनाया जाता है। हमारी कनेक्ट क्लाइंट गिनती आमतौर पर 1000-1500 से होती है। सर्वर 64 जीबी मेमोरी के साथ नए मॉडल का 8-कोर xeon है और सेवा के बाद और कुछ नहीं चलाता है।

समस्या: एक्स समय के बाद, यह एक दिन से एक सप्ताह तक हर जगह रहा है, सेवा बहुत धीमी हो जाती है। अनुरोध जो 0.5 सेकंड लेते हैं, एक मिनट से अधिक समय ले सकते हैं। यह व्यवहार 15-40 मिनट तक चलता है या फिर सेवा को पुनरारंभ करने के लिए चला जाता है।

हमने जो किया है: हमने सर्वर से नेटवर्क और नेटवर्क कनेक्शन की जांच की है और कोई समस्या नहीं है। सीपीयू उपयोग f.eks से इस समय के दौरान कुछ हद तक ऊपर चला जाता है। 30% औसत 40-50% औसत। हमने मेमोरी डंप लिया है और कोड में कोई लॉजिकल लॉक नहीं है जो उपयोगकर्ताओं को अवरुद्ध करता है और बहुत अधिक गतिविधि नहीं करता है। हमारा नवीनतम नेतृत्व कचरा कलेक्टर है। पेर्फॉन में हम देख सकते हैं कि "जीसी में% समय" लगातार 90% से अधिक है, (9 0-97%) और संग्रह गणना बढ़ जाती है। जीसी 0 और जीसी 1 दोनों। हमें संदेह है कि एक अवरुद्ध जीसी 2 भी चल रहा है, लेकिन हमें उत्पादन में पुन: प्रारंभ करना पड़ा क्योंकि यह उत्पादन में है इसलिए यह 5 मिनट की खिड़की के दौरान गिनती नहीं हुई थी जिसे हम परफमन चलाते थे। मेमोरी उपयोग 7,6 जीबी था। नोट: बकाया बढ़ता है इसलिए कॉल वहां जाती है लेकिन सेवा उन्हें संभाल नहीं देती है।

मेरे प्रश्न हैं, क्या कचरा कलेक्टर एक ऐसे राज्य में हो सकता है जहां यह लगातार 15 मिनट से अधिक समय तक चलता है और ब्लॉक करता है? या समस्या शायद किसी अन्य मुद्दे से संबंधित हैं?

हमारी सेवा वर्कस्टेशन मोड और विलंबता मोड में जीसी चलाती है: इंटरएक्टिव हमने अब इसे सर्वर और सस्टेन लोलाटाेंसी में बदल दिया है और उम्मीद है कि इससे कुछ हद तक मदद मिलेगी। क्या कचरा कलेक्टर अगर हम कुछ और कर सकते हैं?

संपादित करें: बड़ी मेमोरी उपयोग डिज़ाइन द्वारा है, कैश में डेटा इतना बड़ा है और वहां बहुत अधिक स्मृति उपलब्ध है।

+0

स्मृति के उच्च उपयोग के मूल कारण को जानने के लिए सुझाव दें ... उदा। उस ऑब्जेक्ट का उपयोग करके समाप्त होने के बाद "मेमोरी" ब्लॉक को मुफ्त मेमोरी में जोड़ने का प्रयास करें – User2012384

+0

जिज्ञासा से बाहर, आपके पास कितने धागे हैं? कार्य प्रबंधक में जांचें। कम से कम कुछ साल पहले एक समस्या थी कि आपके पास जितने अधिक धागे थे (यहां तक ​​कि निष्क्रिय भी), धीमी गति से जीसी – xanatos

+2

"क्या कचरा कलेक्टर एक ऐसे राज्य में हो सकता है जहां यह लगातार 15 मिनट से अधिक समय तक चलता है और ब्लॉक करता है"? बिल्कुल, अगर इसे लगातार स्मृति मुक्त करने की आवश्यकता होती है लेकिन ऐसा करने में असमर्थ है क्योंकि आप इसे पकड़ते रहते हैं। जैसा कि रेमंड चेन ने कहा, "एक बुरी नीति वाला कैश मेमोरी लीक के लिए एक और नाम है"। –

उत्तर

4

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

वास्तव में extensive checklist available on MSDN है जो आपको समस्या का निदान करने में मदद कर सकता है।

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

+0

हमारा सबसे बड़ा कैश एक अपरिवर्तनीय संग्रह कम या कम है, यह पूछे जाने पर डेटा जोड़ता है और इसकी अनुपलब्धता है। उसके बाद आइटम में 4 घंटे का टीटीएल होता है यदि इसे दोबारा एक्सेस नहीं किया जाता है तो काउंटर रीसेट हो जाता है। तो यह काफी सरल है। एक आम परिदृश्य यह है कि यह दिन में शुरुआती 1-1,5 जीबी तक बढ़ता है। फिर 0.5 जीबी नया डेटा जोड़ता है और 0,5 जीबी हटा देता है और रात में यह पूरी तरह से साफ़ हो जाता है। यदि यह समस्या है तो यह समस्या है कि मैं जीसी को दिन के दौरान इसे स्पर्श न करने और इसे रात में स्कैन करने में सक्षम होना चाहता हूं। क्या मैं इस व्यवहार को प्राप्त करूंगा यदि मैं सस्टेनलोलाइटेंसी सेट करता हूं और फिर रात में gc.collect को मजबूर करता हूं? –

+0

जोहान: यदि आप इसे सेट करते हैं तो जीसी दिन में एक बार से अधिक बार आती है। जीसी एक सतत प्रक्रिया है। ['GCLatencyMode'] पर टिप्पणी अनुभाग पर ध्यान दें (https://msdn.microsoft.com/en-us/library/system.runtime.gclatencymode%28v=vs.110%29।एएसपीएक्स): "अगर सिस्टम मेमोरी प्रेशर में है तो पूर्ण अवरोधन संग्रह अभी भी हो सकता है।" –

+0

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

0

मेरे पास एक समान स्थिति है। क्लाइंट संचार के लिए डब्ल्यूसीएफ के साथ protobuf का उपयोग कर एक सेवा में बड़े डेटाबेस डेटा कैश। कैश पूरी तरह से ग्राहकों के लिए नहीं है, व्यवसाय परत संचालन करने के लिए कैश का उपयोग करती है। सेवा की स्मृति पदचिह्न 2 और 10 जीबी के बीच कहीं भी हो सकती है। मैं 8 घंटे निष्क्रियता के बाद कैश का एक खंड जारी करता हूं। मशीन में 8 वर्चुअल कोर और 32 जीबी मेमोरी है। मैं नेट 4.5.1 का उपयोग कर रहा हूँ।

जीसी डाटाबेस से कैश लोड होने पर एक घंटे के लिए 98% CPU का उपभोग करेगा। यहां हमारे दोनों मामलों में दिलचस्प बिंदु कोई स्मृति दबाव नहीं है।

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

1) कैश से हटाए गए टुपल्स। मैं उन्हें शब्दकोश कुंजी के रूप में उपयोग कर रहा था और संरचनात्मक गुणवत्ता के उनके कार्यान्वयन भयानक है। यह ऑब्जेक्ट्स के रूप में सभी गुणों की तुलना करता है, इसलिए गुणों के लिए बहुत सारी मुक्केबाजी चल रही है जो मूल्य हैं और इन्हें किसी बिंदु पर कचरा इकट्ठा करना होगा।

2) जब टुपल्स को चाबियों के रूप में इस्तेमाल किया जाता है तो मैं उन्हें समान रूप से कार्यान्वित किए बिना संरचनाओं के साथ प्रतिस्थापित नहीं कर सकता क्योंकि मूल्य तुलना प्रतिबिंब का उपयोग करती है और यह बहुत महंगा है इसलिए मैंने जेनेरिक जोयर संरचना तैयार की। मैंने ऑब्जेक्ट्स में ऑब्जेक्ट्स की संख्या को हटाने के लिए संरचनाओं का उपयोग करने का निर्णय लिया।

3) टुपल्स को हटाने के लिए मुझे अपनी खुद की जोड़ी संरचना बनाना पड़ा जो संपत्ति प्रकारों के लिए डिफ़ॉल्ट बराबर का उपयोग करके गुणों की तुलना करता है। वही वही बात जो PowerCollections ने बनाई है।

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