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

时间:2011-10-26 00:51:20

标签: android gridview garbage-collection scroll

我一直在看这个很长一段时间,最后决定发布 - 我的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个滚动,然后停止。但是只要我按下菜单会弹出一个2进入菜单或切换活动并回来,GC也会回来。

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

我联系了Romain Guy,他说我应该尝试分配跟踪。我跑了跟踪并轻弹,但在我自己的代码中看不到任何分配。我确实看到了分配,然后是调用 com.android.internal.os.BinderInternal在finalize中分配的$ GcWatcher,它匹配logcat中GC行的数量。以下是整个分配跟踪器转储(或as a picture更容易解析):

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 

正如您所看到的,直接在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    

这是我的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>

每个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>

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

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问题Lots of garbage collection in a listview但不幸的是它似乎不适用于GridViews。

此外,我似乎并不是唯一遇到此问题的人 - 我的一位朋友联系我,在他的应用中完全独立地询问完全相同的问题。

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

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

谢谢。

3 个答案:

答案 0 :(得分:19)

在随机尝试更多内容之后,我相信我能够通过在XML中将GridView的scrollingCache设置为false来解决问题。它现在已经很顺利了。

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。

答案 1 :(得分:2)

这也是ListViews的一个问题,频繁的世界末日垃圾收集会导致最终用户体验不佳,并导致用户将Android归咎于不稳定的UI性能。但是,通过将scrollingCache设置为false,也可以通过相同的方式解决此问题。

答案 2 :(得分:1)

使用SimpleCursorAdapter和ListActivity中使用的自定义2行ListView布局,没有图像只是文本,我有CacheColorHint - #00000000。 在开始之前,我会说快速解决方法是删除cachecolorhint,但我需要它,所以它不是GC的修复程序....

我现在和过去有同样的问题,但是这会抛出一个曲线球...我有两个应用程序,它们本质上是彼此的镜像。一个人运行得很好,没有猖獗的垃圾收集在logcat中,它滚动得很漂亮,另一个不能很好地工作,没有任何东西,没有复制和粘贴的代码可以将它从一个固定到另一个。

另外!...有时候在应用程序中运行效果不佳,当我从查询中获取列表并使用稍微不同的列表视图布局时,我可以使其工作。不要妄下结论,因为如果我离开并返回,在自定义2行列表项布局上使用简单游标适配器的相同排序查询将再次导致GC。换句话说,有时它会简单地正常工作,有时则不会。请注意,我在两个应用程序中都保留了“scrollingCache”作为默认值,因为我说它们是彼此的副本。

前段时间我遇到了这个并且能够以某种方式解决它并且它与ScrollingCache无关。相反,它与我的构建编译反对某些旧版本的Android(我认为)我的内存不是100%肯定,但我发誓修复与构建/编译器问题有关。如果我记得修理它的话,我会发帖。我使用Surround,所以我正在寻找变化。 我希望这是有道理的