क्या नेविगेशन आर्क कंपोनेंट एक झूठी सकारात्मक मेमोरी लीक बना सकता है?


14

मुझे स्मृति लीक का एक बुनियादी ज्ञान है और उनके कारण क्या हो सकते हैं। इसलिए मुझे समझ नहीं आ रहा है कि क्या मुझे अपने कोड में कोई समस्या है या क्या यह गलत सकारात्मक है। मुझे नहीं पता कि परियोजना का कौन सा हिस्सा मुझे साझा करना चाहिए क्योंकि प्रोजेक्ट छोटा नहीं है। लेकिन बस मुझे टिप्पणियों में बताएं और मैं आवश्यक कोड जोड़ दूंगा।

मैं नेविगेशन आर्क घटक का उपयोग करता हूं और MVVM पैटर्न का पालन करता हूं। मैंने LeakCanary लाइब्रेरी को बाद में प्रोजेक्ट के विकास में शामिल किया और स्क्रीन के बीच नेविगेट करने पर यह मुझे तुरंत पूर्व चेतावनी के बारे में चेतावनी देना शुरू कर दिया।

समस्या तब होती है जब मैं बैक स्टैक में टुकड़े जोड़ देता हूं। प्रत्येक जोड़ के टुकड़े के साथ पीछे ढेर करने के लिए बनाए रखा उदाहरणों के काउंटर बढ़ जाती है। जब यह 5 LeakCanary के थ्रेसहोल्ड मान तक पहुँचता है और ढेर को रिपोर्ट करता है।

लेकिन अगर मैं बैक बटन पर क्लिक करता हूं और पिछले स्क्रीन पर लौटता हूं, तो बनाए गए इंस्टेंस के काउंटर कम हो जाते हैं और आखिरकार, जब 1 स्क्रीन पर वापस आते हैं, तो सभी इंस्टेंस इंस्टेंसेस गायब हो जाते हैं।

अगर मैं ढेर विश्लेषण रिपोर्टों को देखता हूं तो यह कहता है कि चर समन्वयकलेयूट जो कि CoordinatorLayoutxml में एक संदर्भ है लीक हो गया है। यदि मैं चर और उसके सभी उपयोग को हटा देता हूं और फिर से ऐप चलाता हूं तो मुझे वही समस्या दिखाई देती है, लेकिन अब एक अन्य चर के साथ जो कि xml में किसी अन्य दृश्य का संदर्भ है। मैंने उन सभी विचारों और उनके उपयोग को हटाने की कोशिश की जो लीककैनरी ने लीक होने की सूचना दी थी। जब यह कहा गया कि एक TextView, जिसका उपयोग सिर्फ एक पाठ को सेट करने के लिए onViewCreatedकिया जाता है और कहीं और उपयोग नहीं किया जाता है, तो मैं लीक कर रहा हूं मुझे संदेह है कि मेरे कोड में कोई समस्या है।

मैंने टुकड़ों में जीवनचक्र पद्धति के कॉलों का विश्लेषण किया और देखा कि जब मैं पिछली विखंडन के लिए नई स्क्रीन पर नेविगेट करता हूं, तब तक सभी विधियों onDestroyViewको कॉल किया जाता है और इसमें कॉल भी जाता है लेकिन नहीं onDestroy। जब मैं वापस क्लिक करता हूं तो onDestroyउस खंड के लिए कॉल किया जाता है जो बैक स्टैक के शीर्ष पर था और बनाए गए उदाहरण काउंटर घट जाते हैं।

मुझे संदेह है कि नेविगेशन घटक एक खंड का उदाहरण रख रहा है जब यह बैक स्टैक में है और लीककैनरी इसे लीक के रूप में देख रहा है।

जवाबों:


24

यह है कि बैक स्टैक के काम पर फ्रेगमेंट (और नेविगेशन केवल मौजूदा फ्रैगमेंट एपीआई का उपयोग करता है): फ्रैगमेंट का दृश्य नष्ट हो जाता है, लेकिन फ्रैगमेंट स्वयं नष्ट नहीं होता है - वे CREATEDराज्य में तब तक रखे जाते हैं जब तक आप बैक बटन को हिट नहीं करते हैं और फ्रैगमेंट में वापस नहीं आते हैं। (जिसके बाद onCreateView()फिर से बुलाया जाएगा और आप वापस ऊपर जाएंगे RESUMED)।

फ्रेगमेंट्स के अनुसार : पास्ट, प्रेजेंट और फ्यूचर टॉक , भविष्य में आने वाले परिवर्तनों में से एक दो अलग-अलग जीवनचक्रों के बजाय, बैक स्टैक पर फ्रैगमेंट्स को नष्ट करने का एक विकल्प है। यह अभी तक उपलब्ध नहीं है।

आपको अपने संदर्भों को अपने संदर्भों से अलग करना होगा onDestroyViewक्योंकि यह संकेत है कि दृश्य का उपयोग अब Fragment सिस्टम द्वारा नहीं किया जा रहा है और यह सुरक्षित रूप से कचरा एकत्र किया जा सकता है यदि यह आपके निरंतर संदर्भ के लिए नहीं था।


2
क्या Android View बाइंडिंग इस समस्या को हल करता है? मुझे इस बात पर कोई दस्तावेज़ नहीं मिल रहा है कि क्या बाइंडिंग व्यूज़ (शायद बाइंडिंग ऑब्जेक्ट स्वयं) का संदर्भ स्वचालित रूप onDestroyViewसे व्यू बाइंडिंग के साथ 'शून्य' हो गया है ।
टिम मालसीड

3
@TimMalseed - आपको अपने आप को बाइंडिंग ऑब्जेक्ट के संदर्भ में शून्य करने की आवश्यकता है, स्वचालित रूप से कुछ भी नहीं चल रहा है।
इयानहनिबलेक

1
@ इमानुएल - आपको अपने संदर्भ को बाइंडिंग ऑब्जेक्ट पर छोड़ने की आवश्यकता है क्योंकि यह उस दृश्य के लिए एक कठिन संदर्भ रखता है जो उसका मालिक है।
इयानहनिबल्के 13


1
@ इम्मानुएल - मुझे लगता है कि यह निश्चित रूप से व्यवहार में बदलाव होगा (जो कि ध्वज में एक अलग विकल्प हो सकता है), लेकिन सही LifecycleOwner होने से इसके लिए स्मृति के मुद्दों की एक पूरी कड़ी को ठीक करने के लिए पर्याप्त जानकारी होगी।
38हनुनीबालक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.