जैसा कि शीर्षक कहता है, मेरे पास लेआउट लोड करने पर स्मृति अपवाद को फेंक दिया गया है। एक सोचता है कि यह एक स्मृति रिसाव मुद्दा है, लेकिन इसे 2 दिनों के लिए लड़ने के बाद अब मुझे इतना यकीन नहीं है। ऐप में 10+ गतिविधियां हैं, जिनमें से अधिकांश पृष्ठभूमि छवियां हैं।OutOfMemoryError बिटमैप्स बनाने
कुछ तथ्यों/खोजों मैंने बनाया:
अब तक इस मुद्दे को केवल Android 4.0.3 चल Galaxy Nexus के लिए प्रकट होता है। मैं नेक्सस एस (4.1.1) और गैलेक्सी एस II (2.3.3) पर इसे पुन: उत्पन्न करने में असमर्थ था।
स्क्रीन अभिविन्यास बदल नहीं है। वास्तव में मेरी अधिकांश गतिविधियां वैसे भी पोर्ट्रेट पर बंद हो गईं।
सिर्फ हंसी के लिए मैंने नई गतिविधि खोलते समय
finish()
पर कॉल जोड़ा, इसलिए उस समय स्मृति में एक से अधिक गतिविधि नहीं होगी। सत्यापित है किonDestroy
कहा जा रहा है।
परिभाषित:
@Override
public void onDestroy()
{
super.onDestroy();
cleanupDrawables(contentView);
// null all the fields referencing views and drawables
System.gc();
}
जहां cleanupDrawables()
है:
protected static void cleanupDrawables(View view)
{
cleanupDrawable(view.getBackground());
if (view instanceof ImageView)
cleanupDrawable(((ImageView)view).getDrawable());
else if (view instanceof TextView)
{
TextView tv = (TextView)view;
Drawable[] compounds = tv.getCompoundDrawables();
for (int i = 0; i < compounds.length; i++)
cleanupDrawable(compounds[i]);
}
else if (view instanceof ViewGroup && !(view instanceof AdapterView))
{
ViewGroup vg = (ViewGroup)view;
for (int i = 0; i < vg.getChildCount(); i++)
cleanupDrawables(vg.getChildAt(i));
vg.removeAllViews();
}
}
protected static void cleanupDrawable(Drawable d)
{
if (d == null)
return;
d.setCallback(null);
if (d instanceof BitmapDrawable)
((BitmapDrawable)d).getBitmap().recycle();
else if (d instanceof LayerDrawable)
{
LayerDrawable layers = (LayerDrawable)d;
for (int i = 0; i < layers.getNumberOfLayers(); i++)
cleanupDrawable(layers.getDrawable(i));
}
}
ग्रहण ढेर निरीक्षक को देखते हुए, स्मृति स्थिर प्रतीत होता है, यानी कुछ गतिविधियों को और अधिक स्मृति ले दूसरों की तुलना में, लेकिन इसे बंद करने पर जारी किया जाता है, और यह समय के साथ स्थिर दिखाई देता है।
एसओ छवियों पर संबंधित उत्तरों के अनुसार मूल स्मृति में संग्रहीत किया जाता है, लेकिन this दोस्त का दावा है कि उन्हें एंड्रॉइड 3 के बाद से ढेर पर होना चाहिए, इसलिए अगर यह वास्तव में छवि स्मृति रिसाव था तो मुझे स्मृति वृद्धि दिखाई देनी चाहिए।
मेरे प्रयासों का अंतिम परिणाम यह है कि मुझे अभी भी स्मृति त्रुटि से बाहर निकलना है, हालांकि जितना तेज़ मैंने पहले किया था। त्रुटि होने से पहले मैं दृश्यमान बिटमैप भ्रष्टाचार देखना शुरू कर देता हूं, जो cleanupDrawables()
कोड जोड़ने से पहले मामला नहीं था। मैंने यह अनुमान लगाया कि Bitmap.recycle()
पर कॉल भ्रष्टाचार का कारण बन रहा है, भले ही यह कोड केवल onDestroy
पर कॉल किया गया हो। भ्रष्टाचार दोनों बिटमैप्स पर दिखाई देता है जो कई गतिविधियों पर दिखाई देने वाली सामान्य शैलियों के कुछ हिस्सों के साथ-साथ बिटमैप केवल एक गतिविधि पर दिखाए जाते हैं।
मेरी जांच के कम परिणामों में बल्कि असुविधाजनक हैं। इस बिंदु पर मुझे नहीं पता कि और क्या प्रयास करना है।
संदर्भ के लिए त्रुटि स्टैक ट्रेस:
08-22 10:49:51.889: E/AndroidRuntime(31697): java.lang.RuntimeException: Unable to start activity ComponentInfo{klick.beatbleeds/klick.beatbleeds.Bleeds}: android.view.InflateException: Binary XML file line #67: Error inflating class <unknown>
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1955)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.app.ActivityThread.access$600(ActivityThread.java:122)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.os.Handler.dispatchMessage(Handler.java:99)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.os.Looper.loop(Looper.java:137)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.app.ActivityThread.main(ActivityThread.java:4340)
08-22 10:49:51.889: E/AndroidRuntime(31697): at java.lang.reflect.Method.invokeNative(Native Method)
08-22 10:49:51.889: E/AndroidRuntime(31697): at java.lang.reflect.Method.invoke(Method.java:511)
08-22 10:49:51.889: E/AndroidRuntime(31697): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
08-22 10:49:51.889: E/AndroidRuntime(31697): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
08-22 10:49:51.889: E/AndroidRuntime(31697): at dalvik.system.NativeStart.main(Native Method)
08-22 10:49:51.889: E/AndroidRuntime(31697): Caused by: android.view.InflateException: Binary XML file line #67: Error inflating class <unknown>
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.view.LayoutInflater.createView(LayoutInflater.java:606)
08-22 10:49:51.889: E/AndroidRuntime(31697): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.view.LayoutInflater.onCreateView(LayoutInflater.java:653)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:678)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
08-22 10:49:51.889: E/AndroidRuntime(31697): at klick.beatbleeds.ActivityBase.setContentView(ActivityBase.java:82)
08-22 10:49:51.889: E/AndroidRuntime(31697): at klick.beatbleeds.Bleeds.onCreate(Bleeds.java:40)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.app.Activity.performCreate(Activity.java:4465)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1919)
08-22 10:49:51.889: E/AndroidRuntime(31697): ... 11 more
08-22 10:49:51.889: E/AndroidRuntime(31697): Caused by: java.lang.reflect.InvocationTargetException
08-22 10:49:51.889: E/AndroidRuntime(31697): at java.lang.reflect.Constructor.constructNative(Native Method)
08-22 10:49:51.889: E/AndroidRuntime(31697): at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.view.LayoutInflater.createView(LayoutInflater.java:586)
08-22 10:49:51.889: E/AndroidRuntime(31697): ... 23 more
08-22 10:49:51.889: E/AndroidRuntime(31697): Caused by: java.lang.OutOfMemoryError
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.graphics.Bitmap.nativeCreate(Native Method)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.graphics.Bitmap.createBitmap(Bitmap.java:605)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.graphics.Bitmap.createBitmap(Bitmap.java:551)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:437)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:524)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:499)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:351)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:773)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.content.res.Resources.loadDrawable(Resources.java:1937)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.view.View.<init>(View.java:2780)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.view.ViewGroup.<init>(ViewGroup.java:385)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.widget.LinearLayout.<init>(LinearLayout.java:174)
08-22 10:49:51.889: E/AndroidRuntime(31697): at android.widget.LinearLayout.<init>(LinearLayout.java:170)
08-22 10:49:51.889: E/AndroidRuntime(31697): ... 26 more
यहाँ दृश्यों में से एक का एक स्क्रीनशॉट कितने छवियों यहाँ उपयोग किया जाता है
तो, कितना बड़ा इन बिटमैप्स (संकल्प) कर रहे हैं? यदि आप उन्हें छोटी छवियों (केवल किक्स के लिए) के साथ बदलते हैं, तो क्या समस्याएं दूर हो जाती हैं? – dmon
दृश्य से क्लीनअप बिटमैप संसाधन आवश्यक नहीं है और केवल एक नई गतिविधि में आपका संक्रमण धीमा कर देगा। आप किस प्रकार का लेआउट फुला रहे हैं और कितनी छवियों के साथ? – DeeV
मैं @Deev से भी सहमत हूं, आपको नष्ट करने पर अपने बिटमैप्स मैन्युअल रूप से "साफ" करने की आवश्यकता नहीं है। – dmon