我一直在看这个很长一段时间,最后决定发布 - 我的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。
这是一个框架错误吗?难道我做错了什么?我不包括某个参数吗?
谢谢。
答案 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,所以我正在寻找变化。 我希望这是有道理的