30

मेरे पास स्विफ्ट में लिखा गया एक आईओएस ऐप है जो स्मृति को लीक कर रहा है - कुछ स्थितियों में कुछ वस्तुओं को रिहा किया जाना चाहिए लेकिन वे नहीं हैं। मैं इस मुद्दे के बारे में बस इस तरह deinit डिबग संदेशों जोड़कर सीखा है:लीक उपकरण उन्हें नहीं दिखाते समय मेमोरी लीक कैसे डिबग करें?

deinit { 
    println("DEINIT: KeysProvider released") 
} 

तो, deinit संदेश इस तरह की घटनाओं है कि वस्तु को रिहा करने का कारण होना चाहिए के बाद कंसोल में मौजूद होना चाहिए। हालांकि, कुछ वस्तुओं को जारी किया जाना चाहिए, संदेश गायब है। फिर भी, लीक्स डेवलपर टूल कोई रिसाव नहीं दिखाता है। मैं ऐसी स्थिति कैसे हल करूं?

+0

मैं सुनिश्चित नहीं हूं यह एक अच्छा परीक्षण है। आपके कोड में कहीं भी हो सकता है जो अभी भी उन दिनचर्या में एक सूचक है। या स्विफ्ट कंपाइलर पर्याप्त है, अगर इसकी आवश्यकता नहीं है तो 'deinit' को कॉल करने के लिए पर्याप्त नहीं है। आपको लीक मेमोरी के लिए बेहतर परीक्षण की आवश्यकता है। – zaph

उत्तर

63

Xcode 8 में, आप डिबग उपकरण पट्टी (स्क्रीन के नीचे दिखाया गया है) में "डीबग मेमोरी ग्राफ़" बटन पर क्लिक कर सकते हैं, debugmemorygraphbutton:

debug memory graph

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

नोटिस, कि सही पैनल में, मैं कॉल पेड़ देख रहा हूं।, वैसे भी

malloc stack

किया है, एक तो तीर पर ढेर में दिखाया गया है प्रासंगिक विधि कॉल करने के लिए क्लिक कर सकते हैं अगले: मुझे लगता है कि इस योजना सेटिंग्स में "malloc ढेर" लॉगिंग विकल्प को चालू करके मिला ऊपर पहले स्क्रीन स्नैपशॉट का सही पैनल में पता लगा, और जैसा कि आप देख सकते हैं, जहां कि मजबूत संदर्भ मूल रूप से स्थापित किया गया था:

code

ऊपर स्मृति नैदानिक ​​तकनीक (और अधिक) WWDC के उत्तरार्द्ध में प्रदर्शित किया गया है 2016 Visual Debugging with Xcode


परंपरागत उपकरण तकनीक (विशेष रूप से उपयोगी अगर एक्सकोड के पुराने संस्करणों का उपयोग कर उपयोगी है) मेरे मूल उत्तर में नीचे वर्णित है।


मैं के साथ उपकरण ' "आवंटन" उपकरण का उपयोग कर सुझाव है कि "रिकार्ड संदर्भ गिनता" सुविधा:

record reference counts

तब आप अपने वर्ग के लिए खोज उपकरण में एप्लिकेशन चला सकते हैं और फिर उस तुम जानते हो लीक और तीर पर क्लिक करके में विस्तार से जानकारी है:

enter image description here

तब आप विवरण और गहराई में जाने और सही पर "विस्तारित विवरण" पैनल का उपयोग कर स्टैक ट्रेस को देखो:

extended details

कि "विस्तारित विवरण" पैनल में, काले रंग में अपने कोड पर ध्यान केंद्रित करने के बजाय प्रणाली में कॉल ग्रे। वैसे भी, "विस्तारित विवरण" पैनल से, आप तो अपने स्रोत कोड में स्मृति समस्याओं को ट्रैक करने साधनों का उपयोग करने में, विश्लेषण कर सकते हैं, उपकरण में सही ::

your code

अधिक जानकारी और प्रदर्शनों के लिए देखें :

+0

धन्यवाद। आपके द्वारा सुझाई गई प्रक्रिया शायद मजबूत चक्रों का पता लगाने के लिए उपकरणों का सबसे अच्छा उपयोग है। हालांकि, यह अभी भी बहुत उपयोगी नहीं है। मैं देख सकता हूं कि फिलहाल कण वर्ग के लिए संदर्भ संख्या क्या है, लेकिन मुझे वास्तव में क्या चाहिए, वह वस्तुएं उन संदर्भों को पकड़ती हैं ... लेकिन यह उपकरणों का खराब डिजाइन है, आपका जवाब बहुत अच्छा है। धन्यवाद! – drasto

+0

यह न केवल आपको दिखाता है कि संदर्भ गणना क्या है, लेकिन अधिक महत्वपूर्ण बात यह है कि यह आपको दिखाता है कि _where_ उन मजबूत संदर्भ स्थापित किए गए थे। मैंने एक उदाहरण के रूप में मजबूत संदर्भ चक्र का उपयोग किया, लेकिन यह किसी भी स्वामित्व परिदृश्य के साथ काम करता है। – Rob

+0

हां, लेकिन यह मुझे दिखाता है कि ** ऑब्जेक्ट के इतिहास के माध्यम से ** सभी ** मजबूत संदर्भ स्थापित किए गए थे। यह सामान्य कार्यक्रम प्रवाह के लगभग कोई उपयोग नहीं है जहां कई संदर्भ बनाए रखा और जारी किया जाता है।मुझे केवल निराश मजबूत संदर्भों में दिलचस्पी है और मुझे केवल उनकी गिनती मिलती है: इस समय उनमें से कितने हैं (बहुत पिछली पंक्ति में रेफॉल्ट कॉलम में संख्या)। उन सभी को बनाए रखा गया और फिर जारी किए गए संदर्भ सिर्फ मेरे लिए टेबल स्पैमिंग कर रहे हैं। उन हिस्सों को खोजने की क्षमता के बिना बहुत अधिक जानकारी मुझे वास्तव में आवश्यकता नहीं होती है, आमतौर पर कोई जानकारी नहीं होती है। – drasto

2

रखरखाव के कारण लीक और स्मृति हानि की जांच करने के लिए उपकरणों का उपयोग करें, लेकिन लीक मेमोरी नहीं। उत्तरार्द्ध अप्रयुक्त स्मृति है जो अभी भी इंगित की गई है। उपकरण पर आवंटन उपकरण में मार्क जनरेशन (हीपशॉट) का प्रयोग करें।

HowTo उपयोग Heapshot स्मृति creap खोजने के लिए के लिए देखें: bbum blog

मूल रूप से विधि, उपकरण उपकरण आवंटित चलाने के लिए, एक heapshot ले अपने कोड का एक यात्रा चलाने के लिए और एक और heapshot दोहरा 3 या 4 बार लेने के लिए है। यह स्मृति को इंगित करेगा जो आवंटन के दौरान आवंटित और जारी नहीं किया गया है।

व्यक्तिगत आवंटन देखने के लिए परिणामों का खुलासा करने के लिए।

तुम कहाँ बरकरार रखे हुए है, विज्ञप्ति और autoreleases एक वस्तु उपयोग उपकरणों के लिए हो देखने के लिए की जरूरत है:

उपकरणों में चलाएँ, पर सेट "रिकार्ड संदर्भ मायने रखता है" आवंटन में (Xcode 5 के लिए और कम आप रिकॉर्डिंग रोकने के लिए विकल्प सेट करने के लिए)। ऐप को चलाने के लिए, रिकॉर्डिंग को रोकें, ड्रिल करें और आप यह देखने में सक्षम होंगे कि सभी बनाए रखने, रिलीज़ और ऑटोरेलीज़ कब हुआ।

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