【发布时间】:2011-10-13 16:55:38
【问题描述】:
这个问题与 Android 中的内存有关。
我的方法:
我有两个活动,A 和 B。我从 A 启动 B,如下所示:
Intent i = new Intent(A.this, B.class);
startActivity(i);
在 B 中单击按钮时,我这样做:
B.this.finish();
- 在 B 中,我重写了 onDestroy 方法并将所有引用设置为 null。
- 我没有在A的onResume方法中分配新内存。
- 我没有泄露上下文。
- 我没有使用多线程。
- 我没有使用服务。
- B中的所有变量都是私有类变量,在B的onDestroy中全部设置为null。
- 另外,B 中的 ImageView 在 B 的 onDestroy 中将其背景设置为 null。
- 我确定 B 会被摧毁。
结果:
当我在活动 A 中时,堆内存为 7.44 MB。然后当我启动 B 并在 B 上调用完成(并因此返回到 A)时,堆增加了 0.16 MB。再次重复此过程,堆每次增加 0.08 MB。
- 我看的不是堆限制,而是分配的堆。
- 我在 B 的 onDestroy 方法结束时调用 System.gc()。
其他信息:
-我已使用 MAT 分析内存分配并尝试找到此泄漏。奇怪的是,活动 B 似乎有 5 个实例。碰巧的是,我重复了 startActivity/finish 过程 5 次。最下面的条目是Activity,其他的是Activity中的监听器:
这是支配树的截图。我找不到任何异常或可疑之处。
-我已经观看了有关内存使用(和泄漏)的两个谷歌 IO 视频。
问题:
无论我做什么,这 0.08 MB 的堆是否可能总是被分配(并且不能被 GC 收集)?如果不是,您知道是什么原因造成的吗?
更新:
我尝试在 B 中未设置内容视图的情况下启动活动 B。这意味着 B 是一个完全空的活动。结果是当我多次重新启动活动时堆内存没有增加。但是请注意,这不是解决方案。我必须能够设置内容视图。
scorpiodawg:我尝试在模拟器上运行我的应用程序,但堆仍在增长。不过还是不错的尝试。
ntc:我将所有出现的“this”更改为可能的“getApplicationContext()”。我无法调用 setContentView(getApplicationContext());因为 setContentView 想要对布局文件的引用,而不是上下文。我所做的是创建一个空布局文件并调用 setContentView(emptylayout);在 Activity B 的 onDestroy 方法中。这没有帮助。
我试图删除所有代码,以便只调用 setContentView(mylayout)。问题依然存在。然后我删除了布局 XML 文件中的所有 gui 元素。问题依然存在。唯一剩下的就是容器视图,几个嵌套的线性布局、相对布局和滚动布局。我试图删除在滚动条中设置“android:scrollbarDefaultDelayBeforeFade”属性。结果很好,内存泄漏消失了。然后我把之前删除但没有设置“android:scrollbarDefaultDelayBeforeFade”属性的所有代码放回去,内存泄漏又回来了。这有多奇怪?
【问题讨论】:
-
但是如果你一次又一次地重复这个过程,你会得到OutOfMemory异常吗?
-
是的,最终我会的。
-
你是如何定义和设置你的听众的?他们是什么样的听众?
-
这个问题与我的听众无关。我尝试删除所有侦听器,但问题仍然存在,堆内存仍然增加。
-
在 MAT 屏幕截图中,我可以看到只有 Listener。您是否在 onDestroy 方法中重置它们? mView.setOnClickListener(null);
标签: java android memory-leaks memory-management