9

हम ईडब्ल्यूएस प्रबंधित एपीआई का उपयोग कर रहे हैं जो किसी दिए गए अंतराल के बाद नए मेल संदेशों के लिए एमएस एक्सचेंज का चुनाव करता है। मतदान कॉल के प्रत्येक आमंत्रण के साथ (PullSubscription.GetEvents()) - माइक्रोस्कोफ्ट एपीआई NetworkStream को सही ढंग से निपटाने में विफल रहा है और स्मृति को आनुपातिक रूप से बढ़ने का कारण बनता है। यह पहले discussed here था, लेकिन कभी हल नहीं हुआ। एएनटीएस प्रोफाइलर का उपयोग करके हम यह निर्धारित करने में सक्षम थे कि कौन सी वस्तुएं स्मृति में लगातार बढ़ रही थीं और इस मुद्दे को अलग कर रही थीं।ऑब्जेक्ट के कचरे के संग्रह को कैसे बल दिया जाए, आप अपमान नहीं कर सकते?

अब यह मुद्दा अलग कर दिया गया है - क्या बाहरी एपीआई में बनाए गए नेटवर्कस्ट्रीम का निपटान करने का कोई तरीका है जिसका हमारे पास कोई संदर्भ नहीं है? जीसी। कोलेक्ट() इसे निपटाने के लिए प्रतीत नहीं होता है क्योंकि इसमें अभी भी एक सक्रिय संदर्भ है। खतरनाक संदर्भ को साफ करने के लिए हम क्या कर सकते हैं? क्या कोई रैपर है जिसका उपयोग हम अपनी छोटी गाड़ी एसडीके की सफाई को मजबूर करने के लिए कर सकते हैं?

+0

मुझे आश्चर्य है - क्या आप प्रतिबिंब के माध्यम से संदर्भ प्राप्त कर सकते हैं? –

+0

क्या आप कृपया पोस्ट कर सकते हैं जहां आपने लाइब्रेरी में अनाथ नेटवर्कस्ट्रीम पाया था? मैंने अभी GetEventsMethod के चारों ओर पोक किया है, लेकिन नेटवर्कस्ट्रीम नहीं मिला। –

+0

@ हेनिंगक्रूज़ I ने डैरेन थॉमस के दृष्टिकोण को भी एक प्रयास दिया, लेकिन प्रतिबिंबित करने के लिए मुझे एक्सचेंज सेवा और सदस्यता बॉक्स श्रेणी के आंतरिक में गहन जांच की आवश्यकता होगी जिसे मैंने छोड़ना चुना था। वर्तमान में मैंने अभी साल्वाटोर के # 1 का पालन किया है और एमएस के साथ टिकट खोला है। हम देखेंगे कि आगे क्या होता है ... – SliverNinja

उत्तर

6

किसी संदर्भित ऑब्जेक्ट के लिए स्मृति जारी करने के लिए जीसी को मजबूर करने का कोई तरीका नहीं है!

सबसे पहले मैं इस बग के साथ मदद के लिए माइक्रोसॉफ्ट से संपर्क करने का सुझाव दूंगा।

दूसरा, क्या आप "निपटान" या बस स्मृति रिलीज के बारे में बात कर रहे हैं? वे दो पूरी तरह से अलग चीजें हैं। (पहचानने योग्य पैटर्न, फाइनलाइजर्स)।

तीसरा, क्या आप इन ऑब्जेक्ट्स का संदर्भ दे रहे ऑब्जेक्ट को केवल उन्मूलन कर सकते हैं?

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

+0

4 में आपका गंदे हैक काम करेगा, भले ही फ़ील्ड स्थैतिक न हो। ऐसा लगता है कि कुछ वस्तु है जिसे "अप्रतिबंधित" नहीं होना चाहिए, लेकिन वह (शायद अप्रत्यक्ष रूप से) समस्याग्रस्त वस्तुओं को जिंदा रखता है। – svick

+0

हां, यह विधि सभी परिस्थितियों में काम करती है लेकिन यदि आप किसी ऑब्जेक्ट को केवल उस ऑब्जेक्ट को अस्वीकार कर सकते हैं जो अन्य ऑब्जेक्ट को डिफ्रेंस नहीं कर रहा है और आप ऐसा कर सकते हैं तो मैं बिना किसी गंदे हैक के यह सुझाव दूंगा। –

0

सबसे आसान तरीका एसडीके को अपने AppDomain में इंटरफेस करने वाला हिस्सा चलाएगा और आपके काम किए जाने के बाद ऐपडोमेन को अनलोड कर दिया जाएगा। यह ऐपडोमेन में आवंटित सभी स्मृति को मुक्त करने का कारण बन जाएगा।

लेकिन आपको अपने प्रोजेक्ट में कुछ काम जोड़ने की आवश्यकता होगी क्योंकि आप केवल AppDomainMarshalByRef ऑब्जेक्ट के साथ इंटरचेंज कर सकते हैं या serilizable के रूप में चिह्नित हो सकते हैं।

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

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