2012-07-21 11 views
5

हमारे पास कुछ प्रकार का रिसाव है, जिसकी प्रकृति मुझे समझ में नहीं आती है। Gen0/1/2 ढेर आकार में वृद्धि नहीं करते हैं, हालांकि हम ओम तक कार्य सेट बढ़ते हैं।फ़ाइनलाइज़र कतार बढ़ रहा है लेकिन प्रबंधित हेप्स

DebugDiag मुझसे कहता है कि CLR.DLL बढ़ती स्मृति का मालिक है और भी मुझसे कहता है कि हमारे पास एक बढ़ती finalizer कतार - Texture2D (अपने एक XNA एप्लिकेशन) वस्तुओं जो समय के साथ वृद्धि के हजारों की 100s .. हालांकि कोई प्रोफाइलर (dotTrace , चींटियों, सीएलआर प्रोफाइलर) इन वस्तुओं को पा सकते हैं - वे ढेर में नहीं दिखते हैं और सीएलआरप्रोफाइलर का दावा है कि उन्हें कभी आवंटित नहीं किया जाता है।

तो मैं WinDbg में देखता हूं - एक बार फिर मैं Texture2D से भरा बढ़ती फाइनलाइज़र कतार देख सकता हूं। fReachable खाली है और यह दावा करता है कि उन सभी वस्तुओं को वैसे भी ढेर पर हैं।

*0:038> !finalizequeue 
SyncBlocks to be cleaned up: 0 
MTA Interfaces to be released: 0 
STA Interfaces to be released: 0 
---------------------------------- 
generation 0 has 1881 finalizable objects (33e365b0->33e38314) 
generation 1 has 41580 finalizable objects (33e0dc00->33e365b0) 
generation 2 has 685816 finalizable objects (33b70020->33e0dc00) 
Ready for finalization 0 objects (33e38314->33e38314) 
     MT Count TotalSize Class Name 
......snip...... 
00ce67e0 726827  49424236 Microsoft.Xna.Framework.Graphics.Texture2D* 

फिर मैं उन 726,000 उदाहरणों को देखता हूं ताकि मैं उन्हें ढूंढ सकूं जो उनका मालिक है। समस्या यह है कि डंपीप कहते हैं कि केवल 218 है। मैं जो अपेक्षा करता हूं वह बहुत अधिक है और प्रबंधित प्रोफाइलर्स मुझे क्या बताते हैं।

*0:038> !dumpheap -stat -type Microsoft.Xna.Framework.Graphics.Texture2D 
total 0 objects 
Statistics: 
     MT Count TotalSize Class Name 
00ce67e0  218  14824 Microsoft.Xna.Framework.Graphics.Texture2D 
Total 218 objects* 

तो फाइनेंजर कतार पर शेष आइटम कहां से आ रहे हैं? अभी मुझे स्मृति आवंटन के लिए बढ़ती फाइनलाइज़र कतार पर संदेह है क्योंकि यह बढ़ता है और इसलिए ओओएम बाहर निकलता है। ऐसा लगता है कि कुछ कारणों से उन 218 आइटम को अंतिम बार कतार में कई बार जोड़ा जा रहा है।

बहुत धन्यवाद

एंडी

+0

आप gen0/1/2 ढेर का जिक्र करते हैं, लेकिन बड़ी वस्तुओं के ढेर के बारे में क्या? क्या यह स्थिर है? आम तौर पर लोगों को "ढेर के आकार" से क्या मतलब है? क्या यह ढेर के सभी वस्तुओं का संयुक्त आकार है, या ढेर के लिए आरक्षित स्मृति का आकार है? अगर विखंडन उच्च है, तो ये दो मान अलग हो सकते हैं। – Joh

+0

हाँ यह उल्लेख करने के लिए खेद है कि LOH भी सभी ढेर काउंटर में बाइट्स के रूप में बहुत स्थिर है। आम तौर पर मैं आकार के लिए परफॉर्म काउंटर के बारे में बात कर रहा हूं। जब मैंने सीएलआर प्रोफाइलर से पता लेआउट देखा तो LOH बहुत खंडित नहीं है और इसका समग्र आकार बढ़ रहा नहीं है। लेकिन मैं वापस जाऊंगा और जांच करूँगा। धन्यवाद –

उत्तर

2

पूर्णता के लिए यहां क्या हो रहा था।

XNA के साथ कोई समस्या है जो ReRegisterForFinalize को Texture2Ds पर कॉल करने का कारण बनती है यदि आप डिवाइस का उपयोग करते हैं। मिश्रण [] संग्रह। सनबर्न इस संग्रह को प्रत्येक फ्रेम को अन्य एक्सएनए मुद्दे के आसपास काम करने के लिए एक्सेस करते हैं, इसलिए यदि आपके पास बहुत सारे बनावट हैं तो यह बहुत तेज़ी से बढ़ सकता है।

XNA (Texture3D आदि) में कई जगहें हैं जो समान पैटर्न का उपयोग करती हैं, इसलिए मुझे लगता है कि आप इसे कई तरीकों से दोबारा कर सकते हैं।

चूंकि कोई एक्सएनए 5 का कोई संकेत नहीं है, इसलिए हमें इसके आसपास काम करना पड़ा - मुझे पता चला कि संग्रह को एक्सेस करने के बाद बस सुपरप्रेसफलाइज को कॉल करना अतिरिक्त आइटम को हटा दिया गया था। हम इसे सुरक्षित मानते हैं :-) सनबर्न लोग अपने कोड में एक फिक्स जोड़ रहे हैं और हमें आशा है कि यह मुद्दा दूर हो जाएगा।

1

सकते एक ही उदाहरण को अंतिम रूप देने के लिए कतार में फिर से जोड़ा जा रहा जा सकता है? ऑब्जेक्ट पर दस्तावेज़ों से। फाइनलाइज:

अंतिमकरण स्वचालित रूप से किसी दिए गए उदाहरण पर केवल एक बार बुलाया जाता है, जब तक कि ऑब्जेक्ट को जीसी.र्रेग्रिस्टर फोरफिनलाइज और जीसी। सुपरप्रेसफिनलाइज जैसे तंत्र का उपयोग करके पुनः पंजीकृत नहीं किया जाता है।

यही एकमात्र स्पष्टीकरण है जो आप यहां देख रहे हैं। निश्चित नहीं है कि इसे अंतिम रूप देने के लिए फिर से क्यों पंजीकृत किया जाएगा।

+0

हां यह हो सकता है। मेरे पास कुछ सुझाव हैं कि यह कारण हो सकता है। हालांकि जीसी.ReRegisterForFinalize का उपयोग करने के लिए मेरे पास कोई भी कोड नहीं है जिससे डीबग करना मुश्किल हो जाता है। मुझे पता है कि नेट परावर्तक का नवीनतम संस्करण आपको बाइनरी के अंदर कोड की रेखाओं पर ब्रेकपॉइंट्स की अनुमति देता है, इसलिए मैं कोशिश कर सकता हूं। मेरा WinDbg voodoo इसे कठिन तरीके से करने के लिए पर्याप्त मजबूत नहीं है। –

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