2012-04-08 15 views
1

Ich habe den folgenden Code in einer Aktivität. Letztendlich versuche ich Frame-Animation zu machen, aber der GC bringt Leistung. Ich habe explizit recycelt versucht, aber es macht keinen Unterschied.Android Garbage Collection run Amok

Mir ist auch bewusst, dass ich die Bitmap mit BitmapFactor.Options.inBitmap wiederverwenden kann und das Problem tatsächlich löst, aber mich auf API> = 11 beschränkt, die keine Option ist.

Dieser Code veranschaulicht nur das Problem. Es ist nicht Teil meiner App:

 Log.d("GC_badness", "0: " + SystemClock.uptimeMillis()); 
     Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.my_image); 
     Log.d("GC_badness", "1: " + SystemClock.uptimeMillis()); 
     image = BitmapFactory.decodeResource(getResources(), R.drawable.my_image); 
     Log.d("GC_badness", "2: " + SystemClock.uptimeMillis()); 
     image = BitmapFactory.decodeResource(getResources(), R.drawable.my_image); 
     Log.d("GC_badness", "3: " + SystemClock.uptimeMillis()); 
     image = BitmapFactory.decodeResource(getResources(), R.drawable.my_image); 
     Log.d("GC_badness", "4: " + SystemClock.uptimeMillis()); 
     image = BitmapFactory.decodeResource(getResources(), R.drawable.my_image); 
     Log.d("GC_badness", "5: " + SystemClock.uptimeMillis()); 
     image = BitmapFactory.decodeResource(getResources(), R.drawable.my_image); 
     Log.d("GC_badness", "6: " + SystemClock.uptimeMillis()); 

Dies führt zu den folgenden Protokolleinträgen. Jedes Bitmap-Laden von einer JPG-Ressource führt zu mindestens 3 Speicherbereinigungen und bis zu 8 Speicherungen. In den meisten Fällen sammeln sie nichts oder so gut wie nichts. Der Heap wächst nicht, obwohl es mehrere Nachrichten gibt, die das sagen. Das ist auch ziemlich verwirrend.

Ich bin ratlos. Ich kann keine Möglichkeit finden, meine Bitmap-API 11 wiederzuverwenden, und ich kann nicht mit den riesigen Verzögerungen leben, die all diese nutzlosen Speicherbereinigungen verursachen.

04-07 18:17:51.860: D/GC_badness(7510): 0: 360583998 
04-07 18:17:51.900: D/dalvikvm(7510): GC_FOR_ALLOC freed 34K, 5% free 6320K/6595K, paused 32ms 
04-07 18:17:51.900: I/dalvikvm-heap(7510): Grow heap (frag case) to 7.744MB for 1584016-byte allocation 
04-07 18:17:51.950: D/dalvikvm(7510): GC_FOR_ALLOC freed <1K, 5% free 7867K/8199K, paused 27ms 
04-07 18:17:52.000: D/dalvikvm(7510): GC_CONCURRENT freed <1K, 5% free 7868K/8199K, paused 2ms+3ms 
04-07 18:17:52.030: D/dalvikvm(7510): GC_FOR_ALLOC freed <1K, 5% free 7868K/8199K, paused 31ms 
04-07 18:17:52.030: I/dalvikvm-heap(7510): Grow heap (frag case) to 8.416MB for 704016-byte allocation 
04-07 18:17:52.070: D/dalvikvm(7510): GC_FOR_ALLOC freed <1K, 4% free 8555K/8903K, paused 37ms 
04-07 18:17:52.070: D/dalvikvm(8107): GC_FOR_ALLOC freed 1464K, 39% free 17183K/27911K, paused 62ms 
04-07 18:17:52.100: D/GC_badness(7510): 1: 360584238 
04-07 18:17:52.100: D/dalvikvm(8189): GC_CONCURRENT freed 286K, 8% free 6917K/7495K, paused 17ms+3ms 
04-07 18:17:52.110: D/dalvikvm(7510): GC_CONCURRENT freed 1546K, 22% free 7009K/8903K, paused 2ms+2ms 
04-07 18:17:52.150: D/dalvikvm(7510): GC_FOR_ALLOC freed <1K, 22% free 7008K/8903K, paused 32ms 
04-07 18:17:52.150: I/dalvikvm-heap(7510): Grow heap (frag case) to 8.416MB for 1584016-byte allocation 
04-07 18:17:52.200: D/dalvikvm(7510): GC_FOR_ALLOC freed 0K, 4% free 8555K/8903K, paused 37ms 
04-07 18:17:52.250: D/dalvikvm(7510): GC_CONCURRENT freed <1K, 4% free 8555K/8903K, paused 2ms+2ms 
04-07 18:17:52.280: D/dalvikvm(7510): GC_FOR_ALLOC freed <1K, 4% free 8555K/8903K, paused 30ms 
04-07 18:17:52.280: I/dalvikvm-heap(7510): Grow heap (frag case) to 9.086MB for 704016-byte allocation 
04-07 18:17:52.310: D/dalvikvm(7510): GC_FOR_ALLOC freed 0K, 4% free 9243K/9607K, paused 23ms 
04-07 18:17:52.330: D/dalvikvm(8107): GC_CONCURRENT freed 588K, 34% free 18618K/27911K, paused 4ms+5ms 
04-07 18:17:52.350: D/GC_badness(7510): 2: 360584482 
04-07 18:17:52.350: D/dalvikvm(7510): GC_CONCURRENT freed 1546K, 20% free 7696K/9607K, paused 1ms+2ms 
04-07 18:17:52.380: D/dalvikvm(7510): GC_FOR_ALLOC freed 688K, 28% free 7008K/9607K, paused 22ms 
04-07 18:17:52.380: I/dalvikvm-heap(7510): Grow heap (frag case) to 8.416MB for 1584016-byte allocation 
04-07 18:17:52.400: D/dalvikvm(7510): GC_FOR_ALLOC freed <1K, 11% free 8555K/9607K, paused 21ms 
04-07 18:17:52.440: D/GC_badness(7510): 3: 360584577 
04-07 18:17:52.450: D/dalvikvm(7510): GC_CONCURRENT freed <1K, 4% free 9243K/9607K, paused 1ms+2ms 
04-07 18:17:52.470: D/dalvikvm(7510): GC_FOR_ALLOC freed 2234K, 28% free 7008K/9607K, paused 20ms 
04-07 18:17:52.470: I/dalvikvm-heap(7510): Grow heap (frag case) to 8.416MB for 1584016-byte allocation 
04-07 18:17:52.500: D/dalvikvm(7510): GC_FOR_ALLOC freed 0K, 11% free 8555K/9607K, paused 29ms 
04-07 18:17:52.510: D/dalvikvm(8107): GC_CONCURRENT freed 1785K, 33% free 18832K/27911K, paused 2ms+5ms 
04-07 18:17:52.530: D/GC_badness(7510): 4: 360584668 
04-07 18:17:52.540: D/dalvikvm(7510): GC_CONCURRENT freed <1K, 4% free 9243K/9607K, paused 1ms+2ms 
04-07 18:17:52.570: D/dalvikvm(7510): GC_FOR_ALLOC freed 2234K, 28% free 7008K/9607K, paused 28ms 
04-07 18:17:52.570: I/dalvikvm-heap(7510): Grow heap (frag case) to 8.416MB for 1584016-byte allocation 
04-07 18:17:52.590: D/dalvikvm(7510): GC_FOR_ALLOC freed <1K, 11% free 8555K/9607K, paused 22ms 
04-07 18:17:52.620: D/dalvikvm(7510): GC_CONCURRENT freed <1K, 4% free 9243K/9607K, paused 3ms+2ms 
04-07 18:17:52.630: D/GC_badness(7510): 5: 360584765 
04-07 18:17:52.650: D/dalvikvm(7510): GC_FOR_ALLOC freed 2235K, 28% free 7008K/9607K, paused 21ms 
04-07 18:17:52.650: I/dalvikvm-heap(7510): Grow heap (frag case) to 8.416MB for 1584016-byte allocation 
04-07 18:17:52.680: D/dalvikvm(7510): GC_FOR_ALLOC freed 0K, 11% free 8555K/9607K, paused 27ms 
04-07 18:17:52.710: D/GC_badness(7510): 6: 360584844 

Antwort

1

Warum möchten Sie das Bild wiederverwenden?

Geben Sie dem Müllsammler keine Chance, etwas zu sammeln. Grundsätzlich wird jedes Objekt, das Sie lokal definieren, früher oder später gesammelt.

Verwenden Sie Ihre Bildvariable nicht erneut. Erstellen Sie ein Imagearray und die Bilder vor Ihrem Animationscode (am besten wäre es, während der Aktivität geladen zu werden). Oder erwägen Sie eine ObjectPool für Ihre Bilder zu verwenden.

Hier ist eine gute SO answer auf, wie man Garbage Collection abordet.

Und schließlich finden Sie viele Informationen darüber, wie Garbage Collection zu vermeiden, wenn Sie für google z. "Wie man Müllsammlung Android zu vermeiden".

+0

Ich habe nur ein einzelnes Bild im Beispielcode verwendet. In der App zeige ich viele Bilder an. Auf einem hochauflösenden Bildschirm sind sie groß (1,5 MB), so dass es nicht möglich ist, sehr viele von ihnen nach vorne zu laden. Ich werde ziemlich schnell durch den Haufen kauen. Ich kann sie in Gruppen laden, aber wenn jede Ladung aufgrund von 4 oder 5 GCs eine Pause von 100 ms verursacht, werden sie nicht mit der Bildfrequenz Schritt halten. Ich würde gerne meine eigenen Bitmaps verwalten, aber die BitmapFactory in den frühen APIs unterstützt es einfach nicht. Kurz vor der Programmierung meines eigenen Jpg-Loaders, um BitmapFactorys Bitmaps bei jedem Aufruf neu zuzuordnen, bin ich mir nicht sicher, was ich tun kann. –