2010-09-29 10 views
69

चलें कहना मैं की तरहएंड्रॉइड: बिटमैप रीसायकल() यह कैसे काम करता है?

Bitmap myBitmap = BitmapFactory.decodeFile(myFile); 

अब एक बिटमैप वस्तु में एक छवि लोड किया है अगर मैं की तरह

myBitmap = BitmapFactory.decodeFile(myFile2); 

क्या पहले myBitmap के लिए होता यह कचरा एकत्र हो जाता है या किसी अन्य बिटमैप लोड क्या होगा क्या मुझे एक और बिटमैप लोड करने से पहले मैन्युअल रूप से कचरा इकट्ठा करना है, उदाहरण के लिए। myBitmap.recycle()

इसके अलावा बड़ी छवियों को लोड और उन्हें जिस तरह से

उत्तर

63

पहले बिटमैप GC'ed नहीं है जब आप एक दूसरे को डिकोड पर एक और रीसाइक्लिंग के बाद एक प्रदर्शित करने के लिए एक बेहतर तरीका है। जब भी यह निर्णय लेता है तो जीसी बाद में ऐसा करेगा। यदि आप एएसएपी को मुक्त करना चाहते हैं तो आपको दूसरे बिटमैप को डीकोड करने से पहले रीसायकल() को कॉल करना चाहिए।

यदि आप वास्तव में बड़ी छवि लोड करना चाहते हैं तो आपको इसे दोबारा बनाना चाहिए। यहां एक उदाहरण Strange out of memory issue while loading an image to a Bitmap object है।

20

आपको अगली छवि लोड करने से पहले myBitmap.recycle() को कॉल करने की आवश्यकता होगी।

अपने myFile के स्रोत के आधार पर (उदा। यदि यह कुछ है तो आपके पास मूल आकार पर कोई नियंत्रण नहीं है), बस कुछ मनमानी संख्या को फिर से शुरू करने के बजाय छवि लोड करते समय, आपको छवि को डिस्प्ले आकार में स्केल करना चाहिए।

if (myBitmap != null) { 
    myBitmap.recycle(); 
    myBitmap = null; 
} 
Bitmap original = BitmapFactory.decodeFile(myFile); 
myBitmap = Bitmap.createScaledBitmap(original, displayWidth, displayHeight, true); 
if (original != myBitmap) 
    original.recycle(); 
original = null; 

मैं एक स्थिर में displayWidth & displayHeight कैश है कि मैं अपने गतिविधि के शुरू में प्रारंभ।

Display display = getWindowManager().getDefaultDisplay(); 
displayWidth = display.getWidth(); 
displayHeight = display.getHeight(); 
+3

आपको रीसायकल() को कॉल करने की आवश्यकता नहीं है, अगर आप तुरंत मेमोरी मुक्त करना चाहते हैं तो यह एक अच्छा विचार है। – Karu

+11

स्वीकृत उत्तर कहता है "यदि आप एएसएपी को मुक्त करना चाहते हैं तो आपको रीसायकल()" कॉल करना चाहिए। आपका जवाब कहता है "आपको myBitmap.recycle() को कॉल करने की आवश्यकता होगी"। "चाहिए" और "आवश्यकता" के बीच एक अंतर है, और बाद में इस मामले में गलत है। – Karu

+1

संदर्भ महत्वपूर्ण है। सवाल यह था कि "बड़ी छवियों को लोड करने और रास्ते में एक और रीसाइक्लिंग के बाद उन्हें प्रदर्शित करने का एक बेहतर तरीका भी है"। – djunod

9

एक बार बिटमैप स्मृति में लोड हो गया था, वास्तव में यह दो भाग डेटा द्वारा बनाया गया था। पहले भाग में बिटमैप के बारे में कुछ जानकारी शामिल है, दूसरे भाग में बिटमैप के पिक्सेल के बारे में जानकारी शामिल है (यह बाइट सरणी द्वारा बनाई गई है)। जावा में पहले भाग exisits स्मृति का उपयोग किया, दूसरा भाग सी ++ प्रयुक्त स्मृति में exisits। यह सीधे एक दूसरे की स्मृति का उपयोग कर सकते हैं। Bitmap.recycle() का उपयोग C++ की स्मृति को मुक्त करने के लिए किया जाता है। यदि आप केवल ऐसा करते हैं, तो जीसी जावा का हिस्सा संग्रहित करेगा और सी की स्मृति हमेशा उपयोग की जाती है।

+0

+1 एक रोचक लेकिन बहुत अच्छा तरीका है कि यह वर्णन करने के लिए कि क्यों तत्काल जीसी के लिए स्मृति उपलब्ध नहीं है - अच्छा है। –

17

मुझे लगता है कि समस्या यह है: एंड्रॉइड के प्री-हनीकॉम संस्करणों पर, वास्तविक कच्चे बिटमैप डेटा को वीएम मेमोरी में संग्रहीत नहीं किया जाता है बल्कि मूल स्मृति में। यह मूल स्मृति मुक्त है जब संबंधित जावा Bitmap ऑब्जेक्ट GC'd है।

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

कम से कम यह मेरा अनुमान है। शुक्र है कि हनीकॉम में और बाद में, सभी बिटमैप डेटा वीएम में संग्रहीत है, इसलिए आपको recycle() का उपयोग नहीं करना चाहिए। लेकिन लाखों 2.3 उपयोगकर्ताओं के लिए (विखंडन मुट्ठी हिलाता है), आपको जहां भी संभव हो recycle() का उपयोग करना चाहिए (एक बड़ी परेशानी)। या वैकल्पिक रूप से आप इसके बजाय जीसी का आह्वान करने में सक्षम हो सकते हैं।

7

टिमम्मम सही था।

के अनुसार

: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

इसके अलावा, Android में 3.0 (एपीआई स्तर 11), एक बिटमैप के समर्थन डेटा देशी स्मृति जो एक उम्मीद के मुताबिक तरीके से मुक्त नहीं है में जमा हो गया था, संभवतः एक के कारण पहले इसकी स्मृति सीमा और क्रैश को संक्षेप में पार करने के लिए आवेदन।

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