2012-02-07 13 views
5

में कोड लोड करते समय गंदा मेमोरी रिसाव मेरे पास काम कर रहे कुछ कोड के लिए असामान्य आवश्यकता है। मैं कुछ बारकोड स्कैनिंग करने के लिए एक अविश्वसनीय तृतीय पक्ष लाइब्रेरी का उपयोग कर रहा हूं (यह कई बार चलने के बाद काम करना बंद कर देता है)। इस समस्या को हल करने के लिए मैंने एक अलग ऐपडोमेन में काम करने का फैसला किया और फिर जब मैं समाप्त कर चुका हूं तो ऐपडोमेन को उतारने के लिए।ऐपडोमेन

string domainID = Guid.NewGuid().ToString(); 
AppDomainSetup setup = new AppDomainSetup(); 
AppDomain domain = AppDomain.CreateDomain(domainID, null, setup); 

string result = null; 
try 
{ 
    domain.SetData("stream", stream); 
    domain.DoCallBack(ScanningContext.DoWork); 

    result = domain.GetData("result") as string; 
} 
finally 
{ 
    AppDomain.Unload(domain); 
} 

return result; 

public static void DoWork() 
{ 
    Stream s = AppDomain.CurrentDomain.GetData("stream") as Stream; 
    ObjectHandle handle = AppDomain.CurrentDomain.CreateInstance("Scanning", 
     "Scanner"); 

    Scanning.Scanner scanner = (Scanning.Scanner)handle.Unwrap(); 
    Scanning.Result[] results = scanner.Scan(s); 

    AppDomain.CurrentDomain.SetData("result", results[0].Text); 
} 

"स्कैनर" मैं उपयोग कर रहा हूँ पुस्तकालय के चारों ओर एक आवरण वर्ग है: यह मैं क्या कर रहा हूँ की एक साधारण, लेकिन सटीक, तस्वीर है। यह "स्कैनिंग" असेंबली में बैठता है; इस उद्देश्य के लिए सिर्फ एक अलग परियोजना।

स्कैनिंगकॉन्टेक्स्ट.डॉवर्क एक स्थिर विधि है जो मेरी सेवा की असेंबली में बैठती है।

इस विधि के साथ मेरी समस्या यह है कि वहां कुछ मेमोरी रिसाव है। मेमोरी बढ़ती जा रही है और बढ़ रही है (जब यह कोड निश्चित रूप से कहा जाता है) जब तक आउटऑफमेमरी अपवाद फेंक दिया जाता है।

मुझे कहीं भी रिसाव नहीं मिल रहा है। मेरी सभी धाराओं का निपटारा किया जा रहा है। मेरे सभी बाइट सरणी को हटा दिया जा रहा है। मैं सूची साफ़ कर रहा हूं, सब कुछ जो अतीत में मेरे लिए काम करता है। मुझे लगभग 9 0% विश्वास है कि रिसाव इस ऐपडोमेन सामग्री से संबंधित है। यह मेरा पहला समय है जिसका उपयोग मैं शायद कुछ गलत कर रहा हूं।

मैं ऐपडोमेन्स के अलावा एक और दृष्टिकोण के लिए खुला हूं। मुझे "स्कैनर" कक्षा से परिणामों को वापस करने की क्षमता की आवश्यकता होती है, इसलिए प्रक्रिया को बढ़ाने का विकल्प एक विकल्प नहीं है।

+0

आप कहते हैं कि आप कम से कम दो बार तृतीय पक्ष कोड चला सकते हैं। तो क्या आप ऐप डोमेन का उपयोग करके लीक भी मौजूद है या नहीं, यह जांच कर अंतिम 10% अनिश्चितता से इंकार कर सकते हैं? –

+2

स्कैनर कॉलिंग कोड को हटाएं, एक निश्चित परिणाम लौटाएं और जांचें कि मेमोरी लीक अभी भी वहां है या नहीं, इसके ऐपडोमेन मुद्दे, अन्यथा इसकी तीसरी पार्टी लाइब्रेरी समस्या .. –

+0

पुरानी विधि बहुत सारी मेमोरी का उपभोग करती है, लगभग 250,000k जैसा कि मैं देखता हूं अब यह है, तो यह स्मृति उपयोग अच्छा नहीं है। हालांकि यह मेरे नए दृष्टिकोण की तरह स्मृति से बाहर नहीं चला है। तो अपने प्रश्न का उत्तर देने के लिए, नहीं, मैं अन्य 10% से इनकार नहीं कर सकता, मुझे ऐपडोमेन्स का उपयोग करने के लिए थोड़ा कोड फिर से लिखना पड़ा था, इसलिए मैं उस समय रिसाव पेश कर सकता था। – Matthew

उत्तर

2

AppDomain.Unload विधि डोमेन को अनलोड करने के लिए एक अलग थ्रेड शुरू करता है, जो विभिन्न कारणों से विफल हो सकता है (अप्रबंधित कोड निष्पादित थ्रेड एक समस्या है)। यहां एक नमूना कोड है जो जांचता है कि ऐप डोमेन अनलोड किया गया है (एमएसडीएन डॉक्स से लिया गया है):

try 
{ 
Console.WriteLine(); 
// Note that the following statement creates an exception because the domain no longer exists. 
Console.WriteLine("child domain: " + domain.FriendlyName); 
} 
catch (AppDomainUnloadedException e) 
{ 
Console.WriteLine("The appdomain MyDomain does not exist."); 
} 
संबंधित मुद्दे