Во-первых, вы можете пропустить объекты, если используете метод View.setTag(int, Object)
. Теги, установленные с помощью этого метода, хранятся в статическом WeakHashMap
с ключом View
. Таким образом, если вы храните ссылки на дочернее представление в тегах родительского представления, то все эти представления и контекст, с которым они были созданы (родительское действие), будут пропущены. Это происходит потому, что каждое дочернее представление содержит ссылку на своего родителя, поэтому родительское представление никогда не будет собрано GC.
Существует простой способ смоделировать это поведение:
public static class MainActivity extends ListActivity {
private final WeakHashMap<Parent, Parent.Child> mMap =
new WeakHashMap<Parent, Parent.Child>();
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// If parents were collected OOM error wouldn't be thrown.
// But they aren't collected so we get OOM here.
for (int i = 0; i < 10; ++i) {
Parent parent = new Parent();
mMap.put( parent, parent.mChild );
}
}
}
public static class Parent {
public final Child mChild = new Child();
public class Child {
private final byte[] mJunk = new byte[10*1024*1024];
}
}
Во-вторых, кажется, что класс ListView
вызывает утечку памяти. Это означает, что представление списка, все его переработанные дочерние элементы и родительская активность просочились. Вот некоторая информация об этой ошибке: