Сбор мусора Android GridView (GC_EXTERNAL_ALLOC) 1K чрезмерно, вызывающий очень прерывистый интерфейс

17

Я долго смотрел на это и, наконец, решил опубликовать - мой 2xN GridView, состоящий из ячеек с одним изображением, и часть текста очень изменчивая (но иногда совершенно гладкая). Изучая вывод logcat, я вижу такие вещи, как только я начинаю прокрутку (в списке всего 12 элементов):

10-25 17:28:40.420: D/dalvikvm(12159): GC_EXTERNAL_ALLOC freed 6K, 47% free 3383K/6279K, external 2044K/2161K, paused 38ms
10-25 17:28:40.510: D/dalvikvm(12159): GC_EXTERNAL_ALLOC freed <1K, 47% free 3383K/6279K, external 2044K/2161K, paused 36ms
10-25 17:28:40.600: D/dalvikvm(12159): GC_EXTERNAL_ALLOC freed <1K, 47% free 3383K/6279K, external 2044K/2161K, paused 40ms
10-25 17:28:41.805: D/dalvikvm(12159): GC_EXTERNAL_ALLOC freed 1K, 47% free 3383K/6279K, external 2044K/2161K, paused 34ms
10-25 17:28:41.840: D/dalvikvm(12159): GC_EXTERNAL_ALLOC freed <1K, 47% free 3383K/6279K, external 2044K/2161K, paused 25ms
10-25 17:28:41.880: D/dalvikvm(12159): GC_EXTERNAL_ALLOC freed <1K, 47% free 3383K/6279K, external 2044K/2161K, paused 25ms
10-25 17:28:41.910: D/dalvikvm(12159): GC_EXTERNAL_ALLOC freed <1K, 47% free 3383K/6279K, external 2044K/2161K, paused 20ms
10-25 17:28:41.940: D/dalvikvm(12159): GC_EXTERNAL_ALLOC freed <1K, 47% free 3383K/6279K, external 2044K/2161K, paused 18ms

Это был только один щелчок в нижней части списка и резервное копирование. Очень изменчивый. Если я продолжаю прокручивать вверх и вниз, GC продолжает идти, возможно, 5-6 свитков, а затем останавливается. Но как только я нажимаю Меню, в котором появляется меню с двумя входами или активируется действие и возвращается, GC возвращается тоже.

Я отключил назначения растровых изображений для изображения - та же проблема. Мои ячейки по существу пусты, но GC все еще происходит.

Я связался с Роменом Гаем, который сказал, что я должен попытаться отслеживать распределение. Я запускал отслеживание и щелкнул, но не видел выделения в моем собственном коде. Я видел распределения, за которыми следуют вызовы com.android.internal.os.BinderInternal $ GcWatcher, выделенный в финализации, который соответствует количеству линий GC в logcat. Вот весь дамп Track Allocation Tracker (или как изображение , которое проще разобрать):

1   24  org.apache.harmony.dalvik.ddmc.Chunk    5   org.apache.harmony.dalvik.ddmc.DdmServer    dispatch    
2   12  java.lang.Integer   5   java.lang.Integer   valueOf 
3   24  byte[]  5   dalvik.system.NativeStart   run 
4   20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
5   20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
6   20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
7   20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
8   20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
9   20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
10  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
11  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
12  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
13  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
14  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
15  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
16  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
17  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
18  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
19  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
20  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
21  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
22  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
23  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
24  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
25  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
26  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
27  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
28  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
29  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
30  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
31  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
32  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
33  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
34  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
35  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
36  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
37  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
38  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
39  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
40  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
41  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
42  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
43  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
44  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
45  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
46  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
47  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
48  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
49  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
50  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
51  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
52  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
53  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
54  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
55  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
56  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
57  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
58  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
59  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
60  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
61  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
62  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
63  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
64  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
65  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
66  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
67  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
68  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
69  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
70  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
71  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
72  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
73  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
74  24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
75  36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
76  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
77  24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
78  36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
79  24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
80  36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
81  8   com.android.internal.os.BinderInternal$GcWatcher    2   com.android.internal.os.BinderInternal$GcWatcher    finalize    
82  24  java.lang.ref.WeakReference 2   com.android.internal.os.BinderInternal$GcWatcher    finalize    
83  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
84  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
85  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
86  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
87  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
88  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
89  24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
90  36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
91  24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
92  36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
93  20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
94  24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
95  36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
96  8   com.android.internal.os.BinderInternal$GcWatcher    2   com.android.internal.os.BinderInternal$GcWatcher    finalize    
97  24  java.lang.ref.WeakReference 2   com.android.internal.os.BinderInternal$GcWatcher    finalize    
98  24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
99  36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
100 20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
101 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
102 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
103 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
104 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
105 8   com.android.internal.os.BinderInternal$GcWatcher    2   com.android.internal.os.BinderInternal$GcWatcher    finalize    
106 24  java.lang.ref.WeakReference 2   com.android.internal.os.BinderInternal$GcWatcher    finalize    
107 20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
108 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
109 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
110 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
111 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
112 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
113 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
114 8   com.android.internal.os.BinderInternal$GcWatcher    2   com.android.internal.os.BinderInternal$GcWatcher    finalize    
115 24  java.lang.ref.WeakReference 2   com.android.internal.os.BinderInternal$GcWatcher    finalize    
116 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
117 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
118 20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
119 60  com.carrieriq.iqagent.client.metrics.ui.UI11    1   android.view.ViewRoot   submitPointerMetrics    
120 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
121 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
122 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
123 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
124 8   com.android.internal.os.BinderInternal$GcWatcher    2   com.android.internal.os.BinderInternal$GcWatcher    finalize    
125 24  java.lang.ref.WeakReference 2   com.android.internal.os.BinderInternal$GcWatcher    finalize    
126 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
127 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
128 20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
129 60  com.carrieriq.iqagent.client.metrics.ui.UI11    1   android.view.ViewRoot   submitPointerMetrics    
130 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
131 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
132 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
133 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
134 8   com.android.internal.os.BinderInternal$GcWatcher    2   com.android.internal.os.BinderInternal$GcWatcher    finalize    
135 24  java.lang.ref.WeakReference 2   com.android.internal.os.BinderInternal$GcWatcher    finalize    
136 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
137 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
138 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
139 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
140 20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
141 60  com.carrieriq.iqagent.client.metrics.ui.UI11    1   android.view.ViewRoot   submitPointerMetrics    
142 60  com.carrieriq.iqagent.client.metrics.ui.UI11    1   android.view.ViewRoot   submitPointerMetrics    
143 60  com.carrieriq.iqagent.client.metrics.ui.UI11    1   android.view.ViewRoot   submitPointerMetrics    
144 20  java.util.ArrayList 19  android.os.MessageQueue <init>  
145 36  android.os.MessageQueue 19  android.os.Looper   <init>  
146 24  android.os.Looper   19  android.os.Looper   prepare 
147 144 java.lang.Object[]  19  java.lang.ThreadLocal$Values    initializeTable 
148 32  java.lang.ThreadLocal$Values    19  java.lang.ThreadLocal   initializeValues    
149 16  java.lang.VMThread  1   java.lang.VMThread  create  
150 40  java.util.WeakHashMap$Entry 1   java.util.WeakHashMap   put 
151 16  java.security.ProtectionDomain[]    1   java.security.AccessControlContext  <init>  
152 20  java.security.AccessControlContext  1   java.security.AccessController  getContext  
153 16  java.security.ProtectionDomain[]    1   java.security.AccessController  getStackDomains 
154 24  java.lang.String    1   java.lang.AbstractStringBuilder toString    
155 48  char[]  1   java.lang.AbstractStringBuilder <init>  
156 20  java.lang.StringBuilder 1   java.lang.Thread    create  
157 16  android.view.ViewRoot 1   android.view.ViewRoot   handleLongPress 
158 80  java.lang.Thread    1   android.view.ViewRoot   handleLongPress 
159 60  com.carrieriq.iqagent.client.metrics.ui.UI11    1   android.view.ViewRoot   submitPointerMetrics    
160 24  org.apache.harmony.dalvik.ddmc.Chunk    5   android.ddm.DdmHandleHeap   handleREAQ  
161 17  byte[]  5   android.ddm.DdmHandleHeap   handleREAQ  
162 24  org.apache.harmony.dalvik.ddmc.Chunk    5   org.apache.harmony.dalvik.ddmc.DdmServer    dispatch    
163 12  java.lang.Integer   5   java.lang.Integer   valueOf 
164 24  byte[]  5   dalvik.system.NativeStart   run 

Как вы можете видеть, события, непосредственно предшествующие GC и происходящие между каждым GC, в значительной степени выглядят следующим образом:

107 20  java.util.concurrent.CopyOnWriteArrayList$ListIteratorImpl  1   java.util.concurrent.CopyOnWriteArrayList   iterator    
108 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
109 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
110 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
111 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
112 24  java.lang.ref.SoftReference 1   android.view.View   buildDrawingCache   
113 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
114 8   com.android.internal.os.BinderInternal$GcWatcher    2   com.android.internal.os.BinderInternal$GcWatcher    finalize    
115 24  java.lang.ref.WeakReference 2   com.android.internal.os.BinderInternal$GcWatcher    finalize    

Я действительно хочу, чтобы диспетчер выделения позволял мне экспортировать весь дамп с отдельными трассировками стека, но это не так, поэтому я вставлю несколько трасс стека здесь, большинство из которых связано с рисунком:

android.graphics.Bitmap:

android.graphics.Bitmap nativeCreate    Bitmap.java -2  true    
android.graphics.Bitmap createBitmap    Bitmap.java 477 false   
android.view.View   buildDrawingCache   View.java   6716    false   
android.view.View   getDrawingCache View.java   6567    false   
android.view.ViewGroup  drawChild   ViewGroup.java  1571    false   
android.view.ViewGroup  dispatchDraw    ViewGroup.java  1373    false   
android.widget.AbsListView  dispatchDraw    AbsListView.java    1627    false   
android.widget.GridView dispatchDraw    GridView.java   1943    false   
android.view.View   draw    View.java   7022    false   
android.widget.AbsListView  draw    AbsListView.java    3005    false   
android.view.ViewGroup  drawChild   ViewGroup.java  1646    false   
android.view.ViewGroup  dispatchDraw    ViewGroup.java  1373    false   
android.view.View   draw    View.java   7022    false   
android.view.ViewGroup  drawChild   ViewGroup.java  1646    false   
android.view.ViewGroup  dispatchDraw    ViewGroup.java  1373    false   
android.view.ViewGroup  drawChild   ViewGroup.java  1644    false   

java.util.concurrent.CopyOnWriteArrayList:

java.util.concurrent.CopyOnWriteArrayList   iterator    CopyOnWriteArrayList.java   332 false   
android.view.ViewTreeObserver   dispatchOnPreDraw   ViewTreeObserver.java   570 false   
android.view.ViewRoot   performTraversals   ViewRoot.java   1293    false   
android.view.ViewRoot   handleMessage   ViewRoot.java   1899    false   
android.os.Handler  dispatchMessage Handler.java    99  false   
android.os.Looper   loop    Looper.java 130 false   
android.app.ActivityThread  main    ActivityThread.java 3691    false   
java.lang.reflect.Method    invokeNative    Method.java -2  true    
java.lang.reflect.Method    invoke  Method.java 507 false   
com.android.internal.os.ZygoteInit$MethodAndArgsCaller  run ZygoteInit.java 907 false   
com.android.internal.os.ZygoteInit  main    ZygoteInit.java 665 false   
dalvik.system.NativeStart   main    NativeStart.java    -2  true    

Вот мой XML-контейнер GridView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical" >
  <LinearLayout
    android:id="@+id/scroll_items_holder"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:background="@drawable/app_bg"
    android:orientation="vertical" >
    <LinearLayout
      android:id="@+id/buttonsLayout"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:gravity="center" >
    </LinearLayout>
    <GridView
      android:id="@+id/gridview"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:columnWidth="150dp"
      android:gravity="right"
      android:horizontalSpacing="0dp"
      android:listSelector="@null"
      android:numColumns="auto_fit"
      android:paddingLeft="5dp"
      android:paddingRight="5dp"
      android:stretchMode="columnWidth"
      android:verticalSpacing="10dp" />
  </LinearLayout>
  <include layout="@layout/menu_bar_inc" />
</LinearLayout>

XML-файл для каждой ячейки GridView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/card"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical" >
  <ImageView
    android:id="@+id/thumbnail"
    android:layout_width="fill_parent"
    android:layout_height="120dp"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:layout_marginTop="5dp"
    android:scaleType="centerCrop" />
  <TextView
    android:id="@+id/show_name"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:ellipsize="marquee"
    android:maxLines="1"
    android:textColor="@color/white"
    android:textStyle="bold" />
</LinearLayout>

Адаптер, большинство из которых закомментировано:

package com.tunerfish.tunerfish.adapters;

import java.util.ArrayList;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.tunerfish.tunerfish.core.TfHomeActivity;
import com.tunerfish.tunerfish.databasemanager.dataitem.EntityDataItem;
import com.tunerfish.tunerfish.ui.R;

public class TrendingGalleryAdapter extends BaseAdapter {

  // structure for dumb view holders
  public static class ViewHolder {
    public TextView showName;
    // public ImageViewWithLoader thumbnail;
  }

  // structure for actual data behind the ListView
  public static class EntityData {
    public EntityDataItem entityDataItem;
  }

  public final ArrayList<EntityData> mEntityDataList;

  private final LayoutInflater mInflater;

  public TrendingGalleryAdapter(TfHomeActivity context, ArrayList<EntityData> entityData) {
    mContext = context;
    mInflater = LayoutInflater.from(context);
    mEntityDataList = entityData;
  }

  @Override public int getCount() {
    return mEntityDataList.size();
  }

  @Override public EntityData getItem(int position) {
    return mEntityDataList.get(position);
  }

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

  private final TfHomeActivity mContext;

  @Override public View getView(final int position, View inView, ViewGroup parent) {
    ViewHolder holder;

    if (inView == null) {
      holder = new ViewHolder();
      inView = mInflater.inflate(R.layout.trending_item_mod, null);
      holder.showName = (TextView) inView.findViewById(R.id.show_name);
      // holder.thumbnail = (ImageViewWithLoader) inView.findViewById(R.id.thumbnail);

      inView.setTag(holder);
    } else {
      holder = (ViewHolder) inView.getTag();
    }

    // reset some stuff
    // holder.thumbnail.getImageView().setImageBitmap(null);

    // holder.showName.setText(getItem(position).entityDataItem.getTitle());

    // deal with thumbnails
    String thumbnailUrl = getItem(position).entityDataItem.getTrendingThumbnail();
    // mContext.sendImgDownloadRequest(thumbnailUrl, holder.thumbnail.getImageView(), R.drawable.tunerfish_details_logo2);

    return inView;
  }
}

Итак, этот вопрос может выглядеть долго, но я хотел бы включить как можно больше информации. Я нашел возможную проблему с ListView Множество сборок мусора в списке просмотров но, к сожалению, это не похоже на GridViews.

Кроме того, мне не кажется, что я один с этой проблемой - мой друг связался со мной, чтобы спросить о такой же проблеме в своем приложении совершенно независимо.

Мои тестовые устройства - это OG Droid, работающие на CM 7.1 и Epic 4G Touch, работающие с пряниками.

Так это ошибка структуры? Я делаю что-то неправильно? Я не включаю определенный параметр?

Спасибо.

    
задан Artem Russakovskii 26.10.2011 в 02:51
источник
  • Обязательно ли вы используете параметр convertView в методе getView в своем классе адаптера? –  Kurtis Nusbaum 26.10.2011 в 03:54
  • Код находится прямо над вами - вы можете увидеть его сами. Я считаю, что getView реализован правильно, но это не связано с проблемой. См. Мой ответ ниже. –  Artem Russakovskii 26.10.2011 в 04:05
  • К сожалению. Сожалею. Я должен был прочитать ближе. Виноват. –  Kurtis Nusbaum 26.10.2011 в 04:06
  • Ummm ... вы загружаете изображения каждый раз, когда вызывается getView () (sendImgDownloadRequest)? Если это так, вот почему ваш ListView изменчив! Вы выполняете сетевые запросы в потоке пользовательского интерфейса! Используйте asynctasks и кешируйте изображения. –  dmon 26.10.2011 в 04:37
  • @dmon Код показывает, находится ли изображение в кеше и использует кеш в этом случае. Он не загружается каждый раз. Кроме того, я помещал прослушиватель прокрутки и сохранял все запросы на скачивание до тех пор, пока прокрутка не перестанет оптимизировать прокрутку. –  Artem Russakovskii 26.10.2011 в 05:08
Показать остальные комментарии

3 ответа

19

Попробовав больше вещей наугад, я полагаю, что смог решить проблему, установив scrollingCache GridView в false в XML. Теперь он плоский.

Ссылка

Таким образом, параметр, который должен заставить GridView использовать больше памяти и извлечь из кеша быстрее, фактически вызывает только обратное из-за GC, делая его прерывистым. Отключение кеша использует меньше памяти и больше не прерывается.

Это беспроигрышная книга в моей книге, и я надеюсь, что это поможет кому-то в будущем (ಠ_ಠ Google).

Изменить . Просто попробовал это на достойном исполнении ListView, который иногда вызывал GC_EXTERNAL_ALLOC для освобождения небольших объемов памяти. Удаление его из ListView полностью избавило от множества крошечных вызовов GC_EXTERNAL_ALLOC, и остался только случайный больший вызов GC_CONCURRENT. Теперь достойно исполняемый ListView - это великолепный ListView. Таким образом, scrollingCache , похоже, что-то избегать в любом списке и не должно быть включено по умолчанию IMO.

    
ответ дан Artem Russakovskii 26.10.2011 в 03:22
  • Пожалуйста, не делайте общих утверждений, подобных этому, без по-настоящему понимания того, что может происходить. Если scrollingCache был общей проблемой, мы бы не оставили его по умолчанию. Ваша конкретная проблема, вероятно, связана с тем, что ваши элементы списка различаются по размеру. Всякий раз, когда размер кешированного изображения изменяется, его кеш-бит должен быть воссоздан, что не является обычным делом. –  Romain Guy 26.10.2011 в 04:55
  • Мой GridView не отличается по размеру - это одна строка текста + одно изображение с предопределенной высотой. Что касается ListViews, я бы сказал, что ячейки с переменной высотой в ListView являются общими, в большинстве случаев из-за таких вещей, как заголовки, которые могут переполняться более чем на одну строку. –  Artem Russakovskii 26.10.2011 в 05:02
  • В любом случае, я не одинок в этой проблеме, и мне бы хотелось увидеть какие-то объяснения, обсуждения, рекомендации в руководствах и документах API. Здесь есть серьезное впечатление о производительности, и не может помешать сообщить разработчикам, что именно там может возникнуть проблема, даже если это не происходит в каждом случае. –  Artem Russakovskii 26.10.2011 в 05:04
  • Я попытаюсь воспроизвести проблему, когда вернусь к работе. –  Romain Guy 28.10.2011 в 12:47
  • Я добавлю свой голос здесь. Я тестировал это на Android 2.3.4 и придумал те же результаты, что и Артем. Когда scrollcache включен в gridview или listview, есть много активности сборщика мусора, и производительность изменчивая. Когда отключено, GC работает тихо, а производительность - плавная. –  BitBank 31.10.2011 в 06:05
Показать остальные комментарии
2

Это также проблема с ListViews, а частая сборка мусора в стоп-мире вызывает плохой опыт работы с конечными пользователями и приводит к тому, что пользователь винит Android в изнеможении производительности пользовательского интерфейса. Однако эту проблему можно решить так же, установив scrollingCache в false.

    
ответ дан user1077724 02.12.2011 в 16:46
1

Использование SimpleCursorAdapter с пользовательским 2-строчным списком ListView, используемым в ListActivity, без изображений только текста, и у меня есть CacheColorHint - # 00000000. прежде чем я начну, я скажу, что быстрое исправление удаляет cachecolorhint, но мне это нужно, поэтому это не исправление GC, поэтому ....

У меня были проблемы с этой же проблемой сейчас и в прошлом, однако это бросает в нее кривый шар ... У меня есть два приложения, которые по сути являются зеркальными отображениями друг друга. Один будет работать просто отлично, без необузданной коллекции мусора в ловушке, и он красиво прокручивается, другой работает не так хорошо и ничего, никакая копия и вставка кода не могут исправить это из одного в другое.

ТАКЖЕ! ... Иногда в приложении, которое работает не так хорошо, я могу заставить его работать, когда я прибегаю к списку из запроса и использую немного другой макет для представления списка. Не переходите к выводам, потому что, если я перейду и вернусь, тот же отсортированный запрос с использованием простого адаптера курсора на макете пользовательского 2-строчного списка вызовет GC снова. Другими словами, иногда это будет просто работать правильно, а в других случаях - нет. Имейте в виду, что у меня есть «scrollingCache» в качестве значения по умолчанию для обоих приложений, и, как я уже сказал, они являются копиями друг друга.

A назад я столкнулся с этим и смог как-то его решить, и это не имело никакого отношения к ScrollingCache. Скорее, это связано с моей сборкой компиляции против какой-то старой версии Android (я думаю). Моя память не на 100% известна, но я клянусь, что исправление было связано с проблемой сборки / компилятора. Я напишу что-нибудь, если вспомню, что это зафиксировало. Я использую Surround, поэтому я ищу изменения. Надеюсь, это имело смысл

    
ответ дан Zion 16.01.2012 в 05:30
  • Добавьте несколько абзацев, очень трудно прочитать стену с текстом. –  Artem Russakovskii 17.01.2012 в 05:55