Android GridView垃圾收集(GC_EXTERNAL_ALLOC)<1K过度使用,导致UI非常不稳定

Art*_*kii 17 android scroll gridview garbage-collection

我一直在看这个很长一段时间,最后决定发布 - 我的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
Run Code Online (Sandbox Code Playgroud)

这只是在列表底部单击并备份.非常不稳定.如果我继续上下滚动,GC可能会持续5-6个滚动,然后停止.但是只要我按下菜单会弹出一个2进入菜单或切换活动并返回,GC也会回来.

我关闭了图像的位图分配 - 同样的问题.我的细胞基本上是空的,但GC仍然会发生.

我联系了Romain Guy,他说我应该尝试分配跟踪.我跑了跟踪并轻弹,但在我自己的代码中看不到任何分配.我确实看到了分配,然后调用在finalize中分配的com.android.internal.os.BinderInternal $ GcWatcher,它匹配logcat中的GC行数.这是整个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$2 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 
Run Code Online (Sandbox Code Playgroud)

如您所见,直接在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    
Run Code Online (Sandbox Code Playgroud)

我真的希望分配跟踪器允许我使用单独的堆栈跟踪导出整个转储,但它没有,所以我将在这里粘贴一些堆栈跟踪,其中大部分与绘图有关:

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   
Run Code Online (Sandbox Code Playgroud)

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    
Run Code Online (Sandbox Code Playgroud)

这是我的GridView容器XML:

<?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>
Run Code Online (Sandbox Code Playgroud)

每个GridView单元格的XML文件:

<?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>
Run Code Online (Sandbox Code Playgroud)

适配器,其中大部分已注释掉:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

所以,这个问题可能看起来很长,但我希望尽可能多地包含这些信息.我在listview中发现了一个可能相关的ListView问题很多垃圾收集但不幸的是它似乎不适用于GridViews.

此外,我似乎并不孤单于这个问题 - 我的一个朋友联系我,在他的应用程序中完全独立地询问完全相同的问题.

我的测试设备是运行CM 7.1和Epic 4G Touch运行库存姜饼的OG Droid.

这是一个框架错误吗?难道我做错了什么?我不包括某个参数吗?

谢谢.

Art*_*kii 19

随意尝试更多的东西,我相信我是能够通过GridView的设置来解决该问题scrollingCache,以false在XML.它现在是黄油顺利.

http://developer.android.com/reference/android/widget/AbsListView.html#attr_android:scrollingCache

因此,一个应该使GridView使用更多内存并从缓存中快速绘制的设置实际上导致了相反的原因,因为它使得它不稳定.关闭缓存会占用更少的内存,而且不会出现波动.

这在我的书中是双赢的,我希望它能帮助将来的某个人(ಠ_ಠGoogle).

编辑:刚刚在一个表现不错的ListView上尝试过,它偶尔会调用GC_EXTERNAL_ALLOC来释放少量内存.从ListView中删除它完全消除了许多微小的GC_EXTERNAL_ALLOC调用,只剩下偶尔更大的GC_CONCURRENT调用.现在,性能相当不错的ListView是一款性能卓越的ListView.所以scrollingCache似乎在任何列表中都应该避免,并且不应该默认启用IMO.

  • 如果不真正理解可能发生的事情,请不要做出这样的泛型断言.如果scrollingCache是​​一个普遍问题,我们默认情况下不会将其保留.您的特定问题可能是由于您的列表项目大小不一.每当调整缓存视图的大小时,都需要重新创建其位图缓存,这不是常见的情况. (7认同)
  • 我的GridView的大小不变 - 它是一行文本+具有预定义高度的单个图像.对于ListViews,我认为ListView中不同高度的单元格很常见,大部分时间都是由于标题可以溢出到1行以上. (4认同)
  • 无论哪种方式,我并不是唯一一个遇到这个问题的人,我很乐意在指南和API文档中看到某种解释,讨论,建议.这里有一个严重的*性能影响,并且让开发人员知道这就是问题可能存在的地方,即使在每种情况下都不会发生这种情况也不会有害. (4认同)
  • 我回去工作时会尝试重现这个问题. (3认同)
  • 我会在这里添加我的声音.我在Android 2.3.4上进行了测试,得出了与Artem相同的结果.在gridview或listview上启用scrollcache时,会有大量垃圾收集器活动,并且性能不稳定.禁用时,GC会变得安静并且性能平稳. (3认同)