Android: Speichermangel in der Galerie

Meine App zeigt eine Liste von 9 Kategorien und jede Kategorie zeigt einen galerie-basierten Coverflow (freundlicherweise von Neil Davies @ angebotenHie) mit Bildern der ausgewählten Kategorie.
Die Bilder werden aus dem Web abgerufen und in einer ArrayList of Drawables gespeichert. Jede Größe reicht von 300 KB bis 500 KB. Diese Daten werden über einen BaseAdapter (Code unten) an den Coverflow gebunden.
Jedes Mal, wenn ich den Coverflow beende und zur Liste der Kategorien zurückkehre, lösche ich die Array-Liste (wieder Code unten).
In Szenario 1 enthält meine ArrayList 5 Drawables. In diesem Szenario kann ich alle Kategorien frei durchsuchen und ihre Bilder anzeigen. Während meines Tests bin ich 5 Mal durch alle Kategorien gefahren, was ausreicht, um festzustellen, dass es kein Problem gibt.
In Szenario 2 enthält meine ArrayList 10 Drawables. In diesem Szenario erhalte ich eine OutOfMemoryError-Ausnahme, wenn ich Bilder in der 5. oder 6. Kategorie durchsuche:

07-13 08:38:21.266: ERROR/dalvikvm-heap(2133): 819840-byte external allocation too large for this process.
07-13 08:38:21.266: ERROR/(2133): VM won't let us allocate 819840 bytes
07-13 08:38:21.277: DEBUG/skia(2133): --- decoder->decode returned false
07-13 08:38:21.287: WARN/dalvikvm(2133): threadid=25: thread exiting with uncaught exception (group=0x4001b188)
07-13 08:38:21.296: ERROR/AndroidRuntime(2133): Uncaught handler: thread Thread-64 exiting due to uncaught exception
07-13 08:38:21.308: ERROR/AndroidRuntime(2133): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
07-13 08:38:21.308: ERROR/AndroidRuntime(2133):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
07-13 08:38:21.308: ERROR/AndroidRuntime(2133):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:459)
07-13 08:38:21.308: ERROR/AndroidRuntime(2133):     at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:323)
07-13 08:38:21.308: ERROR/AndroidRuntime(2133):     at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
07-13 08:38:21.308: ERROR/AndroidRuntime(2133):     at android.graphics.drawable.Drawable.createFromStream(Drawable.java:657)

Das ergibt für mich keinen Sinn. Wenn mir Speicherplatz entgeht, hätte ich erwartet, dass ich irgendwann in Szenario 1 abstürze, aber ich habe alle Kategorien eine beträchtliche Anzahl von Malen durchlaufen und bin nicht abgestürzt. Ich habe auch das Memory Analyzer-Plugin für Eclipse verwendet, das keine potenziellen Schuldigen darstellte.
Wenn das System nicht mit 10 Bildern umgehen kann, wie in Szenario 2, hätte ich erwartet, dass es in der ersten Kategorie zum Absturz kommt, aber ich stürze erst nach 5 oder 6 Kategorien ab.
Einiger Code:

Die Adapterfunktionen des Coverflows:

public int getCount() {
     return DataManager.getInstance().getImageBufferInstance().getImageArraySize(); 
}

public Object getItem(int position) {    
     return DataManager.getInstance().getImagesBuffer().get(position);
}

public long getItemId(int position) {
     return position;
}

public View getView(int position, View convertView, ViewGroup parent) {      
         ImageView i;
         if (convertView == null)
             i = new ImageView(mContext);
         else
             i = (ImageView)convertView;
         Drawable bufferedImage = (Drawable)getItem(position);
         Log.v("getView", "position: " + position);
         i.setImageDrawable(bufferedImage);

         i.setLayoutParams(new CoverFlow.LayoutParams(Utils.getInstance().getScreenWidth() / 2,
                 Utils.getInstance().getScreenHeight() / 2));
         i.setScaleType(ImageView.ScaleType.CENTER_INSIDE); 

         try{
         //Make sure we set anti-aliasing otherwise we get jaggies
         BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
         drawable.setAntiAlias(true);
         }
         catch (Exception e)
         {
             Log.v("getView", "Exception: " + e.toString());
         }
         return i;      
     }

die Datenquelle beim Eintritt in die Kategorie ausfüllen:

for (int i = 0; i < ImageBuffer.getInstance().getImageArraySize(); i++)  
{  
  String imageUrl = ImageBuffer.getInstance().getImageUrl(i);  
  Log.v("Initial", imageUrl);  
  Drawable fullImage = AsyncImageLoader.getInstance().loadImageByUrl(imageUrl);  
  ImageBuffer.getInstance().getImages().add(i, fullImage);  

}

Löschen der Datenquelle beim Verlassen der Kategorie (in finish ()):

for (int i = 0; i < ImageBuffer.getInstance().getImageArraySize(); i++)  
{  
  if (ImageBuffer.getInstance().images.get(i) != null)  
            {  
                ImageBuffer.getInstance().images.get(i).setCallback(null);  
                ImageBuffer.getInstance().images.set(i, null);  
            }    

}

BEARBEITEN

OK, ich habe die LogHeap-Funktion von Mathias auf meinen Coverflow angewendet und hier sind einige Ausgaben. Vor dem Laden der ersten Galerie:

DEBUG/Application(5221): debug. =================================
DEBUG/Application(5221): debug.heap native: allocated 6.20MB of 6.28MB (0.07MB free) in [com.example.Coverflow]
DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (0.00MB free)
DEBUG/dalvikvm(5221): GC freed 4558 objects / 638152 bytes in 84ms
DEBUG/dalvikvm(5221): GC freed 17 objects / 808 bytes in 67ms

Nach dem Betreten der ersten Galerie:

DEBUG/Application(5221): debug. =================================
DEBUG/Application(5221): debug.heap native: allocated 14.90MB of 16.89MB (0.07MB free) in [com.example.Coverflow]
DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (1.00MB free)
DEBUG/dalvikvm(5221): GC freed 357 objects / 50080 bytes in 68ms
DEBUG/dalvikvm(5221): GC freed 353 objects / 27312 bytes in 67ms

Nachdem die erste Galerie existiert:

DEBUG/Application(5221): debug. =================================
DEBUG/Application(5221): debug.heap native: allocated 14.83MB of 16.89MB (0.11MB free) in [com.example.Coverflow]
DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (1.00MB free)
DEBUG/dalvikvm(5221): GC freed 330 objects / 17920 bytes in 77ms
DEBUG/dalvikvm(5221): GC freed 13 objects / 760 bytes in 67ms

Nach dem Betreten der fünften Galerie:

DEBUG/Application(5221): debug. =================================
DEBUG/Application(5221): debug.heap native: allocated 16.80MB of 23.32MB (0.08MB free) in [com.example.Coverflow]
DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (1.00MB free)
DEBUG/dalvikvm(5221): GC freed 842 objects / 99256 bytes in 73ms
DEBUG/dalvikvm(5221): GC freed 306 objects / 24896 bytes in 69ms

Nach dem Verlassen der fünften Galerie:

DEBUG/Application(5221): debug. =================================
DEBUG/Application(5221): debug.heap native: allocated 16.74MB of 23.32MB (0.11MB free) in [com.example.Coverlow]
DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (1.00MB free)
DEBUG/dalvikvm(5221): GC freed 331 objects / 18184 bytes in 68ms
DEBUG/dalvikvm(5221): GC freed 60 objects / 3128 bytes in 68ms

Es scheint, dass beim Betreten einer Galerie immer mehr Speicher zugewiesen wird, aber nach dem Beenden wird nur sehr wenig Speicher freigegeben. Lösche ich meine Drawables nicht richtig? Für jedes Element in meiner ArrayList of Drawables rufe ich setCallBack (null) auf und setze das Element auf null. Ist das nicht genug?
Verzweifelt nach irgendwelchen Einsichten.
Vielen Dan

Antworten auf die Frage(8)

Ihre Antwort auf die Frage