2011-10-09 18 views
9

मेरे पास एक ऐसा एप्लिकेशन है जो शब्द से धीमी मेमोरी रिसाव का अनुभव करता है।मुझे लटका फाइनलाइज़र कतार का कारण कैसे मिल सकता है?

एएनटीएस मेमोरी प्रोफाइलर का उपयोग करके मैं देख सकता हूं कि सभी लीक मेमोरी फाइनलाइज़र कतार की जीसी रूट द्वारा आयोजित की जा रही है।

मुझे संदेह है कि क्या हो सकता है यह है कि फाइनलर लॉक पर उपलब्ध होने पर प्रतीक्षा कर रहा है।

हमारे वर्गों में से कोई भी स्पष्ट अंतिमकर्ताओं को लागू नहीं करता है, हम उन्हें एक नियम के रूप में टालते हैं, इससे मुझे लगता है कि लॉक किसी सिस्टम या लाइब्रेरी क्लास से संबंधित हो सकता है।

मैं SOS.dll का उपयोग किया है finalizer कतार की सामग्री पर एक नज़र लेने के लिए और फिर इसे पहले आइटम की रिपोर्ट करने पर कतार के सिर वास्तव में प्रतिनिधित्व एक उदाहरण System.Threading.Thread हालांकि मैं अनिश्चित हूं होने के लिए अगर मैं इसे सही ढंग से व्याख्या कर रहा हूँ वर्तमान में निपटान ऑब्जेक्ट या अगली वस्तु का निपटान किया जा रहा है।

  • क्या कोई चाल है जिसे मैं अंतिम रूप देने के लिए उपयोग कर सकता हूं?
  • क्या कोई तरीका है कि मैं यह पता लगा सकता हूं कि फाइनलज़र थ्रेड किस लॉक पर इंतजार कर रहा है?
  • क्या अंतिम अतिरिक्त थ्रेड के कार्यों को खोजने के लिए कोई अतिरिक्त डिबगिंग चालू हो सकती है?
  • मैं और क्या देख सकता हूं?

अद्यतन

finalizer धागा के ढेर के रूप में निम्नानुसार प्रकट होता है:

[email protected]() + 0x15 bytes 
[email protected]() + 0x15 bytes 
[email protected]() + 0x15 bytes  

[email protected]() + 0x43 bytes  
[email protected]() + 0x12 bytes 
ole32.dll!GetToSTA() + 0x72 bytes 

ole32.dll!CRpcChannelBuffer::SwitchAptAndDispatchCall() - 0x1939 bytes 
ole32.dll!CRpcChannelBuffer::SendReceive2() + 0xa6 bytes  
ole32.dll!CAptRpcChnl::SendReceive() + 0x5b7 bytes 
ole32.dll!CCtxComChnl::SendReceive() - 0x14b97 bytes  
ole32.dll!NdrExtpProxySendReceive() + 0x43 bytes  
[email protected]@4() + 0xe bytes  
rpcrt4.dll!_NdrClientCall2() + 0x144 bytes 
[email protected]() + 0x7a bytes  
[email protected]() + 0xf bytes 

ole32.dll!CObjectContext::InternalContextCallback() - 0x511f bytes 
ole32.dll!CObjectContext::ContextCallback() + 0x8f bytes  
clr.dll!CtxEntry::EnterContext() + 0x119 bytes 

clr.dll!RCWCleanupList::ReleaseRCWListInCorrectCtx() + 0x2bb bytes 

clr.dll!RCWCleanupList::CleanupAllWrappers() - 0x20fb0 bytes  
clr.dll!SyncBlockCache::CleanupSyncBlocks() + 0x1ec6 bytes 
clr.dll!Thread::DoExtraWorkForFinalizer() + 0x411b5 bytes 

clr.dll!WKS::GCHeap::FinalizerThreadWorker() + 0x8b bytes 
clr.dll!Thread::DoExtraWorkForFinalizer() + 0xb6e76 bytes 
clr.dll!Thread::ShouldChangeAbortToUnload() - 0x5f8 bytes 
clr.dll!Thread::ShouldChangeAbortToUnload() - 0x53d bytes 
clr.dll!ManagedThreadBase_NoADTransition() + 0x35 bytes  
clr.dll!ManagedThreadBase::FinalizerBase() + 0xf bytes 
clr.dll!WKS::GCHeap::FinalizerThreadStart() + 0xfb bytes  
clr.dll!Thread::intermediateThreadProc() + 0x48 bytes 
[email protected]@12() + 0x12 bytes  
[email protected]() + 0x27 bytes  
[email protected]() + 0x1b bytes  
+1

आप नियम के रूप में अंतिमकर्ता से परहेज क्यों कर रहे हैं? डिस्पोजेबल पैटर्न के उचित कार्यान्वयन * * अंतिमकरण की आवश्यकता है। – svick

+2

@svick - एमएसडीएन पुनः पर एक नोट। कार्यान्वयन आईडीस्पोजेबल कहते हैं, "अगर किसी वर्ग के पास अप्रबंधित संसाधनों का स्वामित्व नहीं है तो अंतिम रूप से अंतिम रूप से बाहर निकलें" – chillitom

+1

@ एसविक - चिलीटॉम सही है। उद्धरण [फ्रेमवर्क डिज़ाइन दिशानिर्देश] (http://www.amazon.com/Framework- डिज़ाइन- दिशानिर्देश- रूपांतरण- पुस्तकालय/डीपी/0321545613): "यदि आप इसकी मदद कर सकते हैं तो आप वास्तव में एक फाइनलाइज़र नहीं लिखना चाहते हैं।" – TrueWill

उत्तर

9

मेरे लिए लग रहा है कि आप एक COM सर्वर के साथ एक समस्या हो रही है। कॉल स्टैक से पता चलता है कि यह एकल-थ्रेडेड COM ऑब्जेक्ट पर IU अज्ञात :: रिलीज़() कॉल करने का प्रयास कर रहा है। रिलीजआरसीडब्लूएलआईटीइनकोर्क्ट सीटीएक्स() कॉल इसे बंद करता है, _NtUserPostMessage @ 16() वह कॉल है जो एसटीए के अनुरोध को मार्शल करता है जो COM ऑब्जेक्ट का मालिक है।

सामान्य कारण COM ऑब्जेक्ट्स बना रहा है और एक संदेश लूप पंप नहीं कर रहा है। एसटीए धागे के लिए एक कठिन आवश्यकता है। आप इसे मुख्य यूआई थ्रेड पर बनाकर इसे कभी भी अवरुद्ध नहीं करते हैं।

+1

स्पॉट पर, प्रोग्राम की मुख्य विधि को एक जीयूआई मोड को समायोजित करने के लिए [STAThread] चिह्नित किया गया था लेकिन आमतौर पर विंडोज सेवा के रूप में चलाया जाएगा। हाल ही में एक COM घटक पेश किया जाना चाहिए, संभावित उम्मीदवार एक टाइमर। जैसा कि आपने यूआई थ्रेड के साथ भविष्यवाणी की है, सेवा का फाइनलाइज़र बस लटकता है। – chillitom

+1

एफवाईआई, यदि आपका मुख्य धागा 'कंसोल। रीडलाइन' जैसा कुछ कर रहा है, लेकिन आप इसे पंपिंग संदेश बनाना चाहते हैं, तो आप रीडलाइन करने के लिए एक नया थ्रेड स्पिन कर सकते हैं और फिर अपने मुख्य से '.Join' का उपयोग कर सकते हैं। धागा। एसटीए थ्रेड पर कॉल किए जाने पर आंतरिक रूप से 'थ्रेड.जॉइन' COM संदेशों को पंप करेगा, जो आपके ऑब्जेक्ट्स को इसका उपयोग करने में सक्षम होना चाहिए। –

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