5

मेरे ऐप में मैं एक सूचीदृश्य और एक सूची एडाप्टर का उपयोग कर रहा हूं। जब कोई सूचीदृश्य में किसी निश्चित उप-साइट पर क्लिक करता है तो एक क्लिक करने योग्य टेक्स्टव्यू होता है जो स्क्रॉलव्यू में कई बिटमैप्स लोड करता है - और यह स्क्रॉलव्यू एक अलर्टडिअलॉग में दिखाया गया है।कमजोर पड़ने के बावजूद स्मृति रिसाव

यह सब उस वर्ग में होता है जो बेसएक्सपैंडेबल लिस्ट एडाप्टर को बढ़ाता है और जब यह टेक्स्टलिंक क्लिक किया जाता है - एक स्थिर आंतरिक वर्ग कहा जाता है जो इन सभी (9) बिटमैप्स को लोड करने के लिए ज़िम्मेदार है। यह आंतरिक वर्ग asynctask फैलाता है।

इन बिटमैप्स को स्क्रॉलव्यू में लोड करने से पहले - इस आंतरिक श्रेणी के दो स्थैतिक तरीकों को स्केलडाउन स्क्रीन के फिट करने वाले आकार के बिटैम्पउन कहा जाता है। यहां मैं बिटमैपफैक्टरी.decoderesource और बिटमैप.scaledown बिटमैप का उपयोग करता हूं।

यह सब ठीक काम करता है, लेकिन कार्यक्रम मेमोरीलेक से पीड़ित है। यह रिसाव इससे पहले बड़ा था क्योंकि यह आंतरिक वर्ग गैर स्थैतिक था। इसलिए लीक इस आंतरिक वर्ग को स्थिर बनाकर कम कर दिया गया था। हाँ - कम हो गया, लेकिन समाप्त नहीं हुआ।

मैंने कई वस्तुओं की कमजोरता भी बनाई है लेकिन सफलता के बिना। उदाहरण के लिए - मैंने ऑब्जेक्ट का कमजोर संदर्भ दिया जो आंतरिक वर्ग को संदर्भित करता है। मैंने संदर्भ के कमजोर संदर्भ को बनाया है जो आंतरिक वर्ग में पारित किया गया है। मैंने बिटमैप्स के कमजोर संदर्भ भी बनाए हैं। बिल्कुल कोई सफलता नहीं

मेरे सैमसंग गैलाज़ी एस 3 का ढेर 64 एमबी है। जब इसके सभी सबिटिम के साथ सूचीदृश्य पहले लोड किया जाता है तो ढेर लगभग 17 एमबी होता है। फिर जब 9 बिटमैप्स लोड होते हैं तो यह लगभग 42 एमबी तक पहुंच जाता है। यदि मैं छवियों के साथ एक और सबिटैम पर क्लिक करता हूं तो ढेर समान होता है - लेकिन बिटमैप्स पर क्लिक करना और लोड करना जारी रखने के बाद अचानक ढेर 47 एमबी तक पहुंच जाता है ... फिर वही परिदृश्य .... अभी भी थोड़ी देर तक खड़ा है - फिर 52 तक एमबी .... 56 एमबी। तो मुझे आउट-ऑफ-मेमोरी प्राप्त करने के लिए बिटमैप्स को बहुत अधिक क्लिक करना और लोड करना होगा। गहन उपयोग के 15-20 मिनट कहें।

निष्कर्ष: आंतरिक श्रेणी के स्थिर बनाने के लिए मुझे स्मृति रिसाव को कम करने में मदद मिली। लेकिन कई वस्तुओं (विशेष रूप से संदर्भ) के कमजोर होने के बावजूद मैं रिसाव को और कम करने में सक्षम नहीं हूं।

कोई सुझाव?

नीचे कोड थोड़ा गंदा ....

static class BitmapWorkerTask extends AsyncTask <Integer, Void, Bitmap[]> { 

     private int[] data; 
     private int[] width, height; 
     private int nmbrOfImages; 
     private String[] scrollText; 
     private ImageView mImage; 
     private View view; 
     private LayoutInflater factory; 
     private AlertDialog.Builder alertadd; 
     private Context context; 
     private WeakReference <Context> sc; 
     private WeakReference <ImageView> mImageV; 
     private WeakReference <Bitmap[]> bitmapV; 

     public BitmapWorkerTask(int[] width, int[] height, int nmbrOfImages, String[] scrollText, Context context) { 

      this.width = width; 
      this.height = height; 
      this.nmbrOfImages = nmbrOfImages; 
      this.scrollText = scrollText; 
      this.context = context; 

      mImage = null; 
      view = null; 
      factory = null; 
      alertadd = null; 
      System.gc(); 

      sc = new WeakReference <Context> (context); 

      try { 
       for (int i = 0; i < scaledBitmap.length; i++) { 
        scaledBitmap[i].recycle(); 
        scaledBitmap[i] = null; 
       } 
      } catch (NullPointerException ne) { 
       System.out.println("nullpointerexception ... gick inte recycla bitmapbilder"); 
      } 

      switch (nmbrOfImages) { 
      case 0: 
       data = new int[1]; 
       break; 
      case 1: 
       data = new int[3]; 
       break; 
      case 2: 
       data = new int[5]; 
       break; 
      case 3: 
       data = new int[9]; 
       break; 
      } 

     } 

     @Override 
     protected Bitmap[] doInBackground(Integer ... params) { 

      switch (nmbrOfImages) { 
      case 0: 
       data[0] = params[0]; 
       break; 
      case 1: 
       data[0] = params[0]; 
       data[1] = params[1]; 
       data[2] = params[2]; 
       break; 
      case 2: 
       data[0] = params[0]; 
       data[1] = params[1]; 
       data[2] = params[2]; 
       data[3] = params[3]; 
       data[4] = params[4]; 
       break; 
      case 3: 
       data[0] = params[0]; 
       data[1] = params[1]; 
       data[2] = params[2]; 
       data[3] = params[3]; 
       data[4] = params[4]; 
       data[5] = params[5]; 
       data[6] = params[6]; 
       data[7] = params[7]; 
       data[8] = params[8]; 
       break; 
      } 

      alertadd = new AlertDialog.Builder(sc.get()); 
      factory = LayoutInflater.from(sc.get()); 
      Bitmap[] bm = decodeSampledBitmapFromResource(sc.get().getResources(), data, width, height); 
      bitmapV = new WeakReference <Bitmap[]> (bm); 

      return bitmapV.get(); 

     } 

     protected void onPostExecute(Bitmap[] bitmap) { 
      switch (nmbrOfImages) { 
       case 0: 

        if (view == null) { 
         view = factory.inflate(R.layout.alertviews, null); 
        } 
        mImage = (ImageView) view.findViewById(R.id.extra_img); 
        mImage.setImageBitmap(bitmap[0]); 
        alertadd.setView(view); 
        alertadd.setNeutralButton("Here!", new DialogInterface.OnClickListener() { 

         public void onClick(DialogInterface dlg, int sumthin) { 

         } 
        }); 
        alertadd.show(); 

       break; 
       case 1: 

        if (view == null) { 
         view = factory.inflate(R.layout.alertviews2, null); 
        } 

        mImage = (ImageView) view.findViewById(R.id.img1); 
        mImage.setImageBitmap(bitmap[0]); 
        mImage = (ImageView) view.findViewById(R.id.img2); 
        mImage.setImageBitmap(bitmap[1]); 
        mImage = (ImageView) view.findViewById(R.id.img3); 
        mImage.setImageBitmap(bitmap[2]); 

        try { 
         TextView mText2 = (TextView) view.findViewById(R.id.text_img1_scrollview); 
         mText2.setText(scrollText[0]); 
         mText2 = (TextView) view.findViewById(R.id.text_img2_scrollview); 
         mText2.setText(scrollText[1]); 
         mText2 = (TextView) view.findViewById(R.id.text_img3_scrollview); 
         mText2.setText(scrollText[2]); 
        } catch (NullPointerException ne) { 
         System.out.println("nullpointerexception ... TextView i metoden onPostExecute"); 
        } 
        alertadd.setView(view); 
        alertadd.setNeutralButton("Here!", new DialogInterface.OnClickListener() { 

         public void onClick(DialogInterface dlg, int sumthin) { 

         } 
        }); 

        alertadd.show(); 

       break; 
       case 2: 

        if (view == null) { 
         view = factory.inflate(R.layout.alertviews3, null); 
        } 
        mImage = (ImageView) view.findViewById(R.id.img1); 
        mImage.setImageBitmap(bitmap[0]); 
        mImage = (ImageView) view.findViewById(R.id.img2); 
        mImage.setImageBitmap(bitmap[1]); 
        mImage = (ImageView) view.findViewById(R.id.img3); 
        mImage.setImageBitmap(bitmap[2]); 
        mImage = (ImageView) view.findViewById(R.id.img4); 
        mImage.setImageBitmap(bitmap[3]); 
        mImage = (ImageView) view.findViewById(R.id.img5); 
        mImage.setImageBitmap(bitmap[4]); 

        try { 
         TextView mText3 = (TextView) view.findViewById(R.id.text_img1_scrollview); 
         mText3.setText(scrollText[0]); 
         mText3 = (TextView) view.findViewById(R.id.text_img2_scrollview); 
         mText3.setText(scrollText[1]); 
         mText3 = (TextView) view.findViewById(R.id.text_img3_scrollview); 
         mText3.setText(scrollText[2]); 
         mText3 = (TextView) view.findViewById(R.id.text_img4_scrollview); 
         mText3.setText(scrollText[3]); 
         mText3 = (TextView) view.findViewById(R.id.text_img5_scrollview); 
         mText3.setText(scrollText[4]); 
        } catch (NullPointerException ne) { 
         System.out.println("nullpointerexception ... TextView i metoden onPostExecute"); 
        } 
        alertadd.setView(view); 
        alertadd.setNeutralButton("Here!", new DialogInterface.OnClickListener() { 

         public void onClick(DialogInterface dlg, int sumthin) { 

         } 
        }); 
        alertadd.show(); 

       break; 
       case 3: 

        if (view == null) { 
         view = factory.inflate(R.layout.alertviews4, null); 
        } 

        AlertDialog.Builder alertadd = new AlertDialog.Builder(context); 



        mImage = (ImageView) view.findViewById(R.id.img1); 
        mImage.setImageBitmap(bitmap[0]); 
        mImage = (ImageView) view.findViewById(R.id.img2); 
        mImage.setImageBitmap(bitmap[1]); 
        mImage = (ImageView) view.findViewById(R.id.img3); 
        mImage.setImageBitmap(bitmap[2]); 
        mImage = (ImageView) view.findViewById(R.id.img4); 
        mImage.setImageBitmap(bitmap[3]); 
        mImage = (ImageView) view.findViewById(R.id.img5); 
        mImage.setImageBitmap(bitmap[4]); 
        mImage = (ImageView) view.findViewById(R.id.img6); 
        mImage.setImageBitmap(bitmap[5]); 
        mImage = (ImageView) view.findViewById(R.id.img7); 
        mImage.setImageBitmap(bitmap[6]); 
        mImage = (ImageView) view.findViewById(R.id.img8); 
        mImage.setImageBitmap(bitmap[7]); 
        mImage = (ImageView) view.findViewById(R.id.img9); 
        mImage.setImageBitmap(bitmap[8]); 



        try { 
         TextView mText4 = (TextView) view.findViewById(R.id.text_img1_scrollview); 
         mText4.setText(scrollText[0]); 
         mText4 = (TextView) view.findViewById(R.id.text_img2_scrollview); 
         mText4.setText(scrollText[1]); 
         mText4 = (TextView) view.findViewById(R.id.text_img3_scrollview); 
         mText4.setText(scrollText[2]); 
         mText4 = (TextView) view.findViewById(R.id.text_img4_scrollview); 
         mText4.setText(scrollText[3]); 
         mText4 = (TextView) view.findViewById(R.id.text_img5_scrollview); 
         mText4.setText(scrollText[4]); 
         mText4 = (TextView) view.findViewById(R.id.text_img6_scrollview); 
         mText4.setText(scrollText[5]); 
         mText4 = (TextView) view.findViewById(R.id.text_img7_scrollview); 
         mText4.setText(scrollText[6]); 
         mText4 = (TextView) view.findViewById(R.id.text_img8_scrollview); 
         mText4.setText(scrollText[7]); 
         mText4 = (TextView) view.findViewById(R.id.text_img9_scrollview); 
         mText4.setText(scrollText[8]); 
        } catch (NullPointerException ne) { 
         System.out.println("nullpointerexception ... TextView i metoden onPostExecute"); 
        } 

       alertadd.setView(view); 

       alertadd.setNeutralButton("Here!", new DialogInterface.OnClickListener() { 

        public void onClick(DialogInterface dlg, int sumthin) { 

        } 
       }); 
       alertadd.show(); 

      break; 
      } 
     } 


     /** 
      * 
      * @param options 
      * @param reqW 
      * @param reqH 
      * @return 
      */ 
      public static int calculateInSampleSize(BitmapFactory.Options options, int reqW, int reqH) { 

       int imageHeight = options.outHeight; 
       int imageWidth = options.outWidth; 
       int inSampleSize = 1; 
       if (imageHeight > reqH || imageWidth > reqW) { 
        int heightRatio = Math.round((float) imageHeight/(float) reqH); 
        int widthRatio = Math.round((float) imageWidth/(float) reqW); 
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 
        System.out.println("i if-satsen!"); 
        System.out.println("height-ratio: " + heightRatio + "\nwidth-ratio: " + widthRatio); 
       } 
       System.out.println("samplesize: " + inSampleSize); 
       inSampleSize = inSampleSize; 

       return inSampleSize; 
      } 

      @SuppressLint("NewApi") 
      /** 
      * 
      * @param res 
      * @param resId 
      * @param reqW 
      * @param reqH 
      * @return 
      */ 
      public static Bitmap[] decodeSampledBitmapFromResource(Resources res, int[] resId, int[] reqW, int[] reqH) { 

       scaledBitmap = new Bitmap[resId.length]; 

       BitmapFactory.Options options; 
       for (int i = 0; i < resId.length; i++) { 
        options = new BitmapFactory.Options(); 
        options.inJustDecodeBounds = true; 
        Bitmap bm =BitmapFactory.decodeResource(res, resId[i], options); 

        System.out.println("ursprunglig bild: h = " + options.outHeight + " w = " + options.outWidth); 
        options.inSampleSize = calculateInSampleSize(options, reqW[i], reqH[i]); 

        while (options.outHeight < reqH[i] || options.outWidth < reqW[i]) { 

         options.inSampleSize--; 
         System.out.println("räknar nu ner insampleseize\ninSamleSize =" + options.inSampleSize); 
        } 

        options.inJustDecodeBounds = false; 

        bm = BitmapFactory.decodeResource(res, resId[i], options); 
        System.out.println("innan omskalning: h = " + options.outHeight + " w = " + options.outWidth); 
        System.out.println("antalet bytes: " + bm.getByteCount()); 
        System.out.println("native free size: " + Debug.getNativeHeapFreeSize()); 

        scaledBitmap[i] = Bitmap.createScaledBitmap(bm, reqW[i], reqH[i], true); 

        bm.recycle(); 
        bm = null; 

       } 
       System.gc(); 
       WeakReference <Bitmap[] > sc = new WeakReference <Bitmap[]> (scaledBitmap); 

       return sc.get(); 
      } 
    } 

}

+2

उपयोग मेट निर्धारित करने के लिए जहां अपने रिसाव हो रहा है। – CommonsWare

उत्तर

2

आप अपने बिटमैप्स को दोहरी संदर्भ रख रहे है एक बार कमजोर और हार्ड कॉपी एक बार आपकी समस्या कोड है:

Bitmap[] bm = decodeSampledBitmapFromResource(sc.get().getResources(), data, width, height); 
       bitmapV = new WeakReference <Bitmap[]> (bm); 

आप बीएम

की सामग्री से छुटकारा नहीं पा रहे हैं

और आप इसे कर रहे हैं एक बार

की तुलना में अधिक

 scaledBitmap[i] = Bitmap.createScaledBitmap(bm, reqW[i], reqH[i], true); 

        bm.recycle(); 
        bm = null; 

       } 
       System.gc(); 
    WeakReference <Bitmap[] > sc = new WeakReference <Bitmap[]> (scaledBitmap); 
आप इस करना चाहिए:

ArrayList<WeakReference<Bitmap>>scaledBitmaps= new ArrayList<WeakReference<Bitmap>>(); 

scaledBitmaps.add(new WeakReference<Bitmap>(Bitmap.createScaledBitmap...)); 

and do not use Bitmap[] array 
संबंधित मुद्दे