2013-02-03 33 views
8

तो मैं MAT है कि मैं हर surfaceCreateमैं इस एंड्रॉइड मेमोरी रिसाव को थ्रेड से कैसे ठीक कर सकता हूं?

मुझे लगता है कि मैं इन धागों की जरूरत है, हालांकि साथ कई Threads बनाने रखने के साथ, मिल गया है, लेकिन यदि कोई उपयोगकर्ता मेरी एप्लिकेशन के माध्यम से नेविगेट के रूप में इस विधि, ViewThread के कई उदाहरण का कारण बनता है, जो एक स्मृति रिसाव है।

मैं अपने धागे बनाए और प्रबंधित किए जाने के तरीके को पुनर्गठित कैसे कर सकता हूं ताकि ऐसा न हो, या मैं रिसाव को रोकने से कैसे रोक सकता हूं?

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    loading=false; 
    if (!mThread.isAlive()){ 
     mThread = new ViewThread(this); 
     mThread.setMenuRunning(true); 
     mThread.start(); 
    } 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 

    if (mThread.isAlive()){ 
     mThread.setMenuRunning(false); 
    } 
} 

मैं खोला और मेरे खेल के Career गतिविधि से दूर नेविगेट पांच बार, और यह क्या MAT

leak

संपादित करें पर दिखाई देता है है: के बाद से पाया गया कि के आधार पर मैंने मेरे धागे के विनाश के लिए surfaceDestroyed अविश्वसनीय है। अब मैं एक अलग विधि से उचित थ्रेड-नष्ट करने वाली कॉल को कॉल करता हूं, ट्रिगर करता हूं।

उत्तर

4

आपको अपने थ्रेड में करियर का संदर्भ देने के लिए वीक रेफरेंस का उपयोग करना चाहिए। कैरियर के लिए कोई और कठिन संदर्भ नहीं होने पर संदर्भ को साफ़ कर दिया जाएगा।

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

+0

मैंने इसे आजमाया, और उन कई उदाहरणों को मेरी कक्षा अभी भी पिलिंग कर रही है। – Houseman

+0

उस स्थिति में आप जीसी जड़ों से वस्तुओं को ऑब्जेक्ट्स में पथ खोजने के लिए MAT का उपयोग कर सकते हैं। आपको शायद श्रोता/पर्यवेक्षक या कुछ में कहीं और संदर्भ मिलेगा। यह एक अज्ञात भीतरी कक्षा हो सकती है। इस मामले में कक्षा के उदाहरण के लिए कमजोर पड़ने के साथ स्थिर वर्गों का उपयोग करने का प्रयास करें। जैसे ही जीसी चलता है, यह लिंक तोड़ देगा। आप उचित पल में श्रोता को मैन्युअल रूप से अपंजीकृत करने का भी प्रयास कर सकते हैं। यदि यह काम नहीं करता है तो क्या आप जीसी जड़ों के पथ दिखाते हुए मैट का एक स्क्रीनशॉट साझा कर सकते हैं? – nickmartens1980

1

surfaceDestroyed के अंदर, आपको का इंतजार करना चाहिए ताकि यह सुनिश्चित किया जा सके कि थ्रेड वापस आने से पहले बंद हो जाए।

आप अधिक जानकारी के लिए, this question का उल्लेख कर सकते

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    boolean retry = true; 
    mThread.setRunning(false); 
    while (retry) { 
     try { 
      mThread.join(); 
      retry = false; 
     } catch (InterruptedException e) { 
     } 
    } 
} 
+0

मैंने कोशिश की, और यह काम नहीं कर रहा था। डंप को देखते समय मैंने अभी भी थ्रेड के कई उदाहरण देखे। – Houseman

1

तो मैं इसे एक लाइन टिप्पणी करके तय:

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    loading=false; 
    if (!mThread.isAlive()){ 
     //mThread = new ViewThread(this); 
     mThread.setMenuRunning(true); 
     mThread.start(); 
    } 
} 

यह भी WeakReference और SurfaceDestroyed जवाब के साथ संयुक्त किया गया था। मैं इसे बाद में परीक्षण करूँगा और यह निर्धारित कर सकता हूं कि यह केवल उस पंक्ति को हटा रहा है, या उसके संयोजन और कमजोर संदर्भ, या दूसरी बात, तो उत्तर

+0

यह सही होगा। मूल सोच में दोष को ध्यान में रखना महत्वपूर्ण है। isAlive() को एक वैध ऑब्जेक्ट संदर्भ की आवश्यकता है और इसलिए यह एक अच्छा संकेतक नहीं है कि आपको एक नई थ्रेड ऑब्जेक्ट की आवश्यकता है या नहीं। isAlive() झूठी वापसी करेगा यदि आपके पास एक वैध थ्रेड है जो सक्रिय नहीं है ... इस प्रकार एक नया थ्रेड बनाना है! isAlive() आपके द्वारा वर्णित व्यवहार में परिणाम देता है।यह तय करने का एकमात्र वैध तरीका है कि कोई नया थ्रेड जोड़ा जाना चाहिए, नल पॉइंटर संदर्भ की जांच करना। वैसे भी शून्य पॉइंटर्स की जांच करना अच्छा अभ्यास है :) –