2017-04-05 9 views
10

उत्पादन में मेरी विंडोज़ सेवा स्थापित करने से पहले, मैं विश्वसनीय परीक्षणों की तलाश कर रहा था जो मैं यह सुनिश्चित करने के लिए कर सकता हूं कि मेरे कोड में स्मृति रिसाव न हो। हालांकि, नेट पर जो कुछ भी मिल सकता है वह प्रयुक्त मेमोरी या कुछ पेड मेमोरी प्रोफाइलर टूल्स देखने के लिए टास्क मैनेजर का उपयोग कर रहा था।एक .NET विंडोज सेवा मेमोरी लीक को ट्रैक करना

मेरी समझ से, कार्य प्रबंधक को देखना वास्तव में सहायक नहीं है और स्मृति रिसाव की पुष्टि नहीं कर सकता है (मामले में, वहां है)।

  1. कैसे पुष्टि करने के लिए एक स्मृति रिसाव है कि क्या वहाँ है या नहीं?

  2. क्या स्मृति लीक के स्रोत को खोजने के लिए कोई निःशुल्क उपकरण है?

नोट: मैं नेट फ्रेमवर्क 4.6 और विजुअल स्टूडियो 2015 का उपयोग कर रहा सामुदायिक

+0

यह सब इस बात पर निर्भर करता है कि आपकी सेवा वास्तव में क्या करती है। – Evk

+0

@Evk चाहे सेवा क्या करती है, मैं कैसे सुनिश्चित कर सकता हूं कि सेवा में कोई स्मृति रिसाव नहीं है? – Mhd

+0

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

उत्तर

7

ठीक है आप कार्य प्रबंधक का उपयोग कर सकते हैं। जीसी ऐप्स स्मृति को रिसाव कर सकते हैं, और यह वहां दिखाएगा।

लेकिन ...

नि: शुल्क उपकरण - "नेट CLR प्रोफाइलर"

वहाँ एक नि: शुल्क उपकरण है, और यह Microsoft से है, और यह कमाल का है। यह उन सभी कार्यक्रमों के लिए जरूरी है जो संदर्भ रिसाव करते हैं। एमएस साइट खोजें।

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

यह जीसी मेमोरी लीक के बराबर है और इसका एक ही परिणाम है। यह कार्यक्रम आपको बताता है कि संदर्भ कितने मेमोरी ले रहे हैं - और आपको पता चलेगा कि यह उस तरह से होना चाहिए या नहीं, और यदि नहीं, तो आप उन्हें ढूंढ सकते हैं और समस्या को ठीक कर सकते हैं!

यह भी एक अच्छी विज़ुअलाइज़ेशन है कि कौन सी वस्तुएं आवंटित करती हैं (ताकि आप गलतियों को ट्रैक कर सकें)। मेरा मानना ​​है कि अगर आपको स्पष्टीकरण की आवश्यकता है तो इसके यूट्यूब हैं।

Memory Usage Visualization

Wikipedia page with download links...

ध्यान दें: आप की संभावना एक सेवा इस का उपयोग करने के रूप में अपने अनुप्रयोग नहीं चलाने के लिए होगा। यह पहले शुरू होता है और फिर आपका ऐप चलाता है। आप इसे टॉपशेल्फ़ के साथ कर सकते हैं या केवल एक डीएल में डालकर डाल सकते हैं जो एक EXE से चलता है जो सेवा एकीकरण (सेवा होस्ट पैटर्न) को लागू करता है।

0

जब तक आप अप्रबंधित कोड के साथ काम कर रहे हैं, मैं इतना कहने के लिए बोल्ड हो जाएगा आप के बारे में चिंता करने की ज़रूरत नहीं है मेमोरी लीक। प्रबंधित कोड में किसी भी अव्यवस्थित वस्तु को कचरा कलेक्टर द्वारा हटा दिया जाएगा, और .NET ढांचे के भीतर मेमोरी लीक खोजने की संभावना मैं कहूंगा कि आपको बहुत भाग्यशाली (अच्छी तरह से, दुर्भाग्यपूर्ण) माना जाना चाहिए। आपको स्मृति रिसाव के बारे में चिंता करने की ज़रूरत नहीं है।

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

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

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

+0

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

+0

@Micael यह सच नहीं है। मेमोरी लीक भी प्रबंधित कोड के कारण हो सकता है। डिस्पोजेड ऑब्जेक्ट्स, प्रतिनिधि सदस्यता, कमजोर संदर्भों के बारे में सोचें ... – Mhd

+0

डिस्पोजेड ऑब्जेक्ट्स अंततः कचरा कलेक्टर द्वारा निपटाया नहीं जाएगा। मुझे लगता है कि यह परिभाषा के लिए नीचे आ गया है। मेमोरी लीक आमतौर पर स्मृति के टुकड़ों को संदर्भित नहीं करती है, लेकिन कुछ भी इसका मतलब नहीं है। स्मृति के चेनिंग भाग जहां प्रत्येक खंड दूसरे संदर्भ में स्मृति स्मृति रिसाव नहीं माना जाता है, बल्कि एक अक्षम संरचना; आप कचरा कलेक्टर को स्मृति मुक्त करने के लिए नहीं चाहते हैं, क्योंकि आपके पास वास्तव में इसे इस तरह रखने का कारण हो सकता है। यह एक स्मृति खाने वाला है, लेकिन यह स्मृति रिसाव नहीं है। – Micael

0

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

enter link description here

यह कोई मजाक या आसान का मतलब है और काफी कठिन है, लेकिन यह अपने सबसे अच्छे शर्त हो जाता है कर रहा है।

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

3

हालांकि प्रबंधित कोड का कोई प्रत्यक्ष स्मृति प्रबंधन नहीं है, फिर भी आपको अपने उदाहरणों का प्रबंधन करना होगा। उन उदाहरणों का दावा 'स्मृति। और यह उन सभी उदाहरणों के उपयोग के बारे में है, जब आप उन्हें उम्मीद नहीं करते हैं तो उन्हें जीवित रखें।

बस कई उदाहरणों में से एक: डिस्पोजेबल कक्षाओं के गलत उपयोग के परिणामस्वरूप स्मृति का दावा करने के कई उदाहरण हो सकते हैं। विंडोज़ सेवा के लिए, उदाहरणों की धीमी लेकिन स्थिर वृद्धि अंततः परिणामस्वरूप बहुत मेमोरी उपयोग कर सकती है।

हां, मेमोरी लीक का विश्लेषण करने के लिए एक उपकरण है। यह सिर्फ मुफ़्त नहीं है। हालांकि आप 7 दिनों के निशान के भीतर अपनी समस्या की पहचान करने में सक्षम हो सकते हैं।

मैं .NET Memory Profiler पर लूट लेने का सुझाव दूंगा।

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

हां, आप यह पुष्टि करने के लिए परीक्षण कर सकते हैं कि मेमोरी लीक पेश किए गए हैं या नहीं। हालांकि, बॉक्स के बाहर यह बहुत उपयोगी नहीं होगा। ऐसा इसलिए है क्योंकि रनटाइम के दौरान क्या होगा, कोई भी उम्मीद नहीं कर सकता है। उपकरण आपके ऐप का विश्लेषण आम मुद्दों के लिए कर सकता है, लेकिन इसकी गारंटी नहीं है।

हालांकि, अगर आप इस उपकरण NUnit या MSTest की तरह अपने इकाई परीक्षण ढांचे में स्मृति की खपत को एकीकृत करने के लिए उपयोग कर सकते हैं।

0

यदि आप एंटिटी फ्रेमवर्क और डीआई पैटर्न का उपयोग करते हैं, तो शायद कैसल विंडसर का उपयोग करके, आप आसानी से मेमोरी लीक प्राप्त कर सकते हैं।

करने के लिए मुख्य बात यह है कि() {} कथन का उपयोग करें जहां आप ऑब्जेक्ट को स्वचालित रूप से डिस्प्ले के रूप में चिह्नित कर सकते हैं।

इसके अलावा, आप एंटीटी फ्रेमवर्क पर स्वचालित ट्रैकिंग बंद करना चाहते हैं जहां आप केवल पढ़ रहे हैं और लिख रहे हैं। अपने लिखने को अलग करने के लिए सर्वश्रेष्ठ, इस बिंदु पर एक() {} का उपयोग करें, एक डीबीकॉन्टेक्स्ट (ट्रैकिंग के साथ) प्राप्त करें, अपना डेटा लिखें।

यदि आप जांच करना चाहते हैं कि ढेर पर क्या है। मेरे द्वारा उपयोग किया जाने वाला सबसे अच्छा टूल रेडगेट एंट्स http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/solving-memory-problems/getting-started सस्ता नहीं है लेकिन यह काम करता है।

हालांकि, उपयोग() {} पैटर्न का उपयोग करके जहां भी आप कर सकते हैं (स्थिर या सिंगलटन डीबीकॉन्टेक्स्ट नहीं बनाते हैं और अपडेट के बड़े पैमाने पर एक संदर्भ नहीं रखते हैं, जितनी बार आप कर सकते हैं उनका निपटान करें !) तो आपको लगता है कि स्मृति अक्सर एक मुद्दा नहीं है।

उम्मीद है कि इससे मदद मिलती है।

2

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

  1. टेस्ट आपकी सेवा:

    यहाँ ज्ञान मैं इस तरह के मुद्दों से निपटने में पिछले कुछ वर्षों में एकत्र किए गए कुछ है। सेवा को वास्तविक सेवा के रूप में जांचने का प्रयास करना चीजों को बहुत जटिल बनाता है।

  2. आप जो कुछ भी कर रहे हैं उसके दायरे के अंत में जो कुछ भी करते हैं, उसे स्पष्ट रूप से पूर्ववत करने की आदत प्राप्त करें। उदाहरण के लिए, यदि आप कुछ पर्यवेक्षकों की स्थिति में पर्यवेक्षक पंजीकृत करते हैं, तो हमेशा समय पर कुछ समय होना चाहिए (पर्यवेक्षक या पर्यवेक्षक का निपटान?) कि आप इसे पंजीकृत करते हैं। सिद्धांत रूप में, कचरा संग्रह को अंतःस्थापित पर्यवेक्षकों के पूरे ग्राफ को इकट्ठा करके उस पर ध्यान रखना चाहिए, लेकिन व्यवहार में, यदि आप जो चीजें करते हैं उन्हें पूर्ववत करने की भूलने की आदत नहीं लेते हैं, तो आपको स्मृति रिसाव मिलती है।

  3. जितना संभव हो सके IDisposable का उपयोग करें, और अगर कोई Dispose() का आह्वान करना भूल गया तो अपने विनाशकों की रिपोर्ट करें। इस विधि के बारे में यहां अधिक जानकारी: Mandatory disposal vs. the "Dispose-disposing" abomination प्रकटीकरण: मैं उस लेख का लेखक हूं।

  4. अपने कार्यक्रम में नियमित चेकपॉइंट्स रखें जहां आप रिलीज करने योग्य सभी चीजों को छोड़ दें (जैसे कि प्रोग्राम समाप्त करने के क्रम में व्यवस्थित शटडाउन कर रहा है) और उसके बाद एक कचरा संग्रह को मजबूर करने के लिए मजबूर करें कि क्या आपके पास कोई रिसाव है या नहीं।

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

1

आप मुक्त Memoscope स्मृति प्रोफाइलर

https://github.com/fremag/MemoScope.Net

मैं सहमत नहीं हूँ कि आप अगर आप एक स्मृति रिसाव है या नहीं की जाँच करने के लिए कार्य प्रबंधक पर भरोसा कर सकते की कोशिश कर सकते। एक कचरा कलेक्टर के साथ समस्या यह है कि यह मेमोरी स्पाइक के बाद मेमोरी रखने के लिए हेरिस्टिक पर आधारित निर्णय ले सकता है और इसे ओएस पर वापस नहीं लौटा सकता है। आपके पास 2 जीबी कमिट आकार हो सकता है लेकिन उनमें से 9 0% मुक्त हो सकते हैं।

परीक्षणों के दौरान जांचने के लिए आपको VMMAP का उपयोग करना चाहिए ताकि आपकी प्रक्रिया में किस प्रकार की मेमोरी हो। आपके पास न केवल प्रबंधित ढेर है, बल्कि अप्रबंधित ढेर, निजी बाइट्स, ढेर (थ्रेड लीक), साझा फाइलें और बहुत कुछ ट्रैक करने की आवश्यकता है।

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

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