2009-10-19 24 views
22

बिटमैप फैक्टरी में अपवाद प्राप्त करना। निश्चित नहीं है कि समस्या क्या है। (ठीक है, मैं इस मुद्दे का अनुमान लगा सकता हूं, लेकिन यह सुनिश्चित नहीं है कि यह क्यों हो रहा है)आउटफमेमरी एरर: बिटमैप आकार वीएम बजट से अधिक है (एंड्रॉइड)

ERROR/AndroidRuntime(7906): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 

ERROR/AndroidRuntime(7906):  at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:295)

मेरा कोड बहुत सीधे आगे है। मैंने एक एक्सएमएल लेआउट डब्ल्यू/एक डिफ़ॉल्ट छवि परिभाषित की है। मैं एसडीकार्ड पर एक बीएम लोड करने की कोशिश करता हूं (यदि मौजूद है - यह है)। यदि नहीं, तो यह डिफ़ॉल्ट छवि दिखाता है।

public class showpicture extends Activity { 
    public void onCreate(Bundle savedInstanceState) { 

     /** Remove menu/status bar **/ 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     final Window win = getWindow(); 
     win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); 

      Bitmap bm; 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.showpicture); 
      try { 
     ImageView mImageButton = (ImageView)findViewById(R.id.displayPicture); 
     bm = Bitmap.createScaledBitmap(BitmapFactory.decodeFile("/sdcard/dcim/Camera/20091018203339743.jpg"),100, 100, true); 
     parkImageButton.setImageBitmap(bm); 
     } 
     catch (IllegalArgumentException ex) { 
      Log.d("MYAPP",ex.getMessage()); 
     } 
      catch (IllegalStateException ex) { 

यह bm=Bitmap.createScaledBitmap कोई विचार पर विफल रहता है: वैसे भी .. यहाँ कोड है? मैंने फ़ोरम पर कुछ शोध किया, और यह this post पर इंगित किया गया कि मुझे नहीं पता कि यह क्यों काम नहीं कर रहा है। कोई भी मदद बहुत अच्छी रहेगी! धन्यवाद,

क्रिस।

+0

कितना बड़ा मूल JPG छवि है? यहां दो 6 एमपीएक्स फाइलों के साथ इस तरह की त्रुटि के बारे में कुछ रिपोर्टें हैं: http://groups.google.com/group/android-developers/browse_thread/thread/0a6279680d1bd15e – schnaader

उत्तर

4
+31

मुझे ऐसे उत्तरों से नफरत है जो सिर्फ लिंक हैं। मुझे गलत मत समझो, लिंक अच्छे हैं, लेकिन यह निश्चित रूप से कोई स्पष्टीकरण वाला लिंक दिखाने के लिए आलसी महसूस करता है। – bugfixr

+0

सहमत हुए। downvoted। – wufoo

1

मुझे लगता है कि यह है - यह क्या कहता है। आपकी छवि बहुत बड़ी है और चूंकि यह स्मृति समाप्त हो जाती है जब स्मृति समाप्त हो जाती है अपवाद फेंक दिया जाता है। यह भी सवाल नहीं है कि आपके पास कितनी मेमोरी है लेकिन आपकी विशेष गतिविधि कितनी उपलब्ध है।

+0

छवि एक जी 1 फोन कैमरा से है। छवि का आकार 2048x1536 एपीएक्स 1.01 एमबी – Chrispix

+0

था कि शोलफ ठीक है लेकिन फिर, - यह संचयी स्मृति नहीं है जो गणना करता है लेकिन सिस्टम द्वारा आपके विशिष्ट कार्य को कितना आवंटित किया गया था। क्या आप सत्यापित कर सकते हैं कि आपका कोड 500K या 50K के साथ काम करता है? – Bostone

4

मैंने निम्न कोड का उपयोग करके बिटमैप का आकार बदलना शुरू कर दिया जो इस मुद्दे को हल कर रहा है।

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inSampleSize = 8; 
Bitmap preview_bitmap = BitmapFactory.decodeFile(mPathName, options); 
4

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

try{    
    Bitmap myFragileBitmap = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888); 
} 
catch(IllegalArgumentException e){ 
    Log.e(TAG,"Illegal argument exception."); 
} 
catch(OutOfMemoryError e){ 
    Log.e(TAG,"Out of memory error :("); 
} 
+0

जीसी करने का सबसे अच्छा तरीका? myFragileBitmap = बातिल? – Chrispix

+0

हमेशा ऐसा नहीं लगता है, किसी कारण से मैं सामान्य रूप से रीसाइक्लिंग के बाद इसे शून्य पर सेट करता हूं ... मुझे लगता है कि बिटमैप समाशोधन के लिए कुछ स्कीया जादू मौजूद है ... – Ralphleon

13

inSampleSize एक अच्छा संकेत है। लेकिन एक निश्चित मूल्य अक्सर ठीक काम नहीं करता है, क्योंकि फाइलों से बड़े बिटमैप आमतौर पर उपयोगकर्ता फाइलें होती हैं, जो छोटे थंबनेल से digicam से 12 एमपी छवियों में भिन्न हो सकती हैं।

यहां एक त्वरित और गंदे लोडिंग दिनचर्या है। मुझे पता है कि सुधार के लिए जगह है, जैसे कि एक अच्छा कोडित पाश, तेजी से डिकोडिंग के लिए 2 की शक्तियों का उपयोग करना, और इसी तरह। लेकिन यह एक काम शुरू है ...

public static Bitmap loadResizedBitmap(String filename, int width, int height, boolean exact) { 
    Bitmap bitmap = null; 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(filename, options); 
    if (options.outHeight > 0 && options.outWidth > 0) { 
     options.inJustDecodeBounds = false; 
     options.inSampleSize = 2; 
     while ( options.outWidth/options.inSampleSize > width 
       && options.outHeight/options.inSampleSize > height) { 
      options.inSampleSize++; 
     } 
     options.inSampleSize--; 

     bitmap = BitmapFactory.decodeFile(filename, options); 
     if (bitmap != null && exact) { 
      bitmap = Bitmap.createScaledBitmap(bitmap, width, height, false); 
     } 
    } 
    return bitmap; 
} 

Btw, नए APIs में वहाँ भी कर रहे हैं DPIs स्क्रीन करने के लिए छवि फिटिंग के लिए BitmapFactory.Option के बहुत सारे है, लेकिन मुझे यकीन है कि क्या वे वास्तव में कुछ को आसान बनाने में नहीं हूँ। Android.util.DisplayMetrics.density का उपयोग करना या कम स्मृति खपत के लिए बस एक निश्चित आकार बेहतर imho काम करने लगते हैं।

0

क्या आपने डीडीएमएस की जांच की है? जो मैं सामना कर रहा हूं उसके साथ, शायद यह छवियों का आकार नहीं है, क्योंकि एंड्रॉइड बड़ी छवियों को अच्छी तरह से संभालने लगता है। यदि आप डीडीएमएस के साथ ढेर का पता लगाते हैं तो आप पाएंगे कि आपके पास बहुत सी मुफ्त मेमोरी है। आप अपने कोड को यह

static { @SuppressWarnings("unused") 
byte dummy[] = new byte[ 8*1024*1024 ]; }  

जोड़कर अपने ढेर "विस्तार" कर सकते हैं, विस्तार करने के लिए मजबूर करने के लिए ढेर। यह इसे थोड़ा कम कर सकता है। दुर्भाग्य से, अपवाद के साथ यह दावा करता है कि यह कुछ बाइट्स आवंटित नहीं कर सकता है। 1 एम कहो यदि आप "मुक्त" रेखा पर नज़र डालते हैं तो आप देखेंगे कि सबसे बड़ा ब्लॉक >> 1 एम है। वहां कुछ अजीब बात है जिसे मैं समझ नहीं सकता। यह छवियों को स्वाइप करने की गति से भी संबंधित नहीं है। मैंने कुछ धागे में देखा कि आप "रीसायकल" या तो बिटमैप्स के लिए कॉल कर सकते हैं। मैं अभी भी नहीं देखता कि क्यों ढेर का आकार लिया गया आकार से ऊपर है।

1

decodefile में इन विकल्पों का उपयोग। आशा है कि .. यू elemenate कर सकते हैं बिटमैप वीएम बजट समस्या अधिक है

BitmapFactory.Options bfOptions=new BitmapFactory.Options(); 

bfOptions.inDither=false;   //Disable Dithering mode 
bfOptions.inPurgeable=true;  //Tell to gc that whether it needs free memory, the Bitmap can be cleared 
bfOptions.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future 
bfOptions.inTempStorage=new byte[32 * 1024]; 
+0

इस विधि ने मदद की, धन्यवाद दोस्त! : डी – Xarialon

0

जब मैं एक छवि (downscale), तो अपने प्रोजेक्ट में आयात (के बाद से मैं बेहतर बनाना चाहते थे 64x240 की तरह कुछ करने के लिए 320x240 से आकार बदलने के लिए शुरू किया मैं यह त्रुटि आई प्रतिपादन गति और इसमें इस बिंदु तक बहुत सारे बेकार अल्फा क्षेत्र शामिल थे)।

अब पिछले जवाब में ज्यादा समझ में आता है:

You can "expand" your heap by adding this static { @SuppressWarnings("unused") byte dummy[] = new byte[ 8*1024*1024 ]; } to your code, to force the heap to expand. It may make it a bit less frequent.

मुझे लगता है यह मुझे क्या हुआ है। एंड्रॉइड स्वचालित रूप से बिटमैप्स में ड्रॉबल्स को डीकोड करता है, (और उसके बाद संकलन समय पर एक ढेर पर संग्रहीत हो जाता है?)

मैंने त्रुटि को देखना शुरू किया, जब मैंने रनटाइम में अपनी छवि के छोटे संस्करण का उपयोग किया (मैं उन्हें रनटाइम पर स्केल करता हूं चूंकि मैं बिटमैपफैक्टरी.decodeResource और Bitmap.createScaledBitmap का उपयोग करके रेट्रो ग्राफिक्स के साथ एक वीजीए-गेम प्रोग्राम करता हूं)।

यह मार्व की तरह होना चाहिए: कहा: ढेर मेरे चित्र में छवि को कम करने और इसे मेरे प्रोजेक्ट में आयात करने के बाद मेरे मामले में काफी बड़ा नहीं है।

छवि को बड़े आकार (320x240) पर वापस आकार देने पर मैं अपने आउटऑफमेमरी अपवाद से छुटकारा पाने में सक्षम था, जो मुझे लगता है कि समस्या का सत्यापन करता है?

5
इस link के संदर्भ के साथ

, कृपया ध्यान दें outOfMemory त्रुटि निम्नलिखित तरीके से हल किया जा सकता है:

public Bitmap decodeFile(String filePath) { 

Bitmap bitmap = null; 
BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inPurgeable = true; 

try { 
BitmapFactory.Options.class.getField("inNativeAlloc").setBoolean(options,true); 

} catch (IllegalArgumentException e) { 
    e.printStackTrace(); 
} catch (SecurityException e) { 
    e.printStackTrace(); 
} catch (IllegalAccessException e) { 
    e.printStackTrace(); 
} catch (NoSuchFieldException e) { 
    e.printStackTrace(); 
} 

if(filePath != null) 
{ 
    bitmap = BitmapFactory.decodeFile(filePath, options);    
} 

return bitmap; 
} 
संबंधित मुद्दे