【发布时间】:2013-12-18 14:41:37
【问题描述】:
在 Activity 上下文中,我有一个带有与每个选项卡关联的 TextViews 的 TabHost。目前还有一个 AsyncTask 管理 TCP 套接字,当它接收到某种信息时,它被发送到主 Activity 处理程序,后者调用一个方法将文本附加到当前 TextView。
好吧,经过一段时间(大约 5 分钟)的运行,我注意到它是如何开始挂起的,最后我得到了 ANR。因此,我安装了 Memory Analyzer for Eclipse 并与 DDMS 结合使用,我能够找出似乎是瓶颈的原因,但不知道如何处理它。
使用前面提到的工具,我可以看到数百行,就像这张照片上的那样:
顺便说一句:那张照片中有一个奇怪的细节,Thread Id 总是 1;由于在不同的线程上调用附加,每个线程不应该有所不同吗?
这数百行引用了您可能在上面的代码中看到的两个“附加”。我是线程世界的新手,所以如果你看到一些奇怪的东西,我会很感激任何建议。这是瓶颈所在的代码:
// tab = is the name of the tab where to append the new text
// line = the line to append; it may contain spans, colors, bold text, etc... that's why it's a SpannableStringBuilder
// ColorLine is a method that just returns a SpannableStringBuilder-formatted string
synchronized private static void Write2Tab(final String tab, final SpannableStringBuilder line) {
final TabHost lth = (TabHost) activity.findViewById(android.R.id.tabhost);
final TextView tabContent = (TextView) lth.getCurrentView();
new Thread(new Runnable() {
public void run() {
String curtab = getCurrentTabName();
// If the current tab is the one where we need to write, we do
if (tab.equalsIgnoreCase(curtab)) {
activity.runOnUiThread(new Runnable() {
public void run() {
tabContent.append(linea);
tabContent.append((ColorLine("\n", Color.WHITE, false, 0, 1)));
}
});
}
}
}).start();
[...]
}
我的代码中还有 2 个内存泄漏,我能够修复,但这一次开始有点困难......关于为什么会发生这种情况以及如何修复它的任何想法?
--------------- 编辑 ---------------
在对我的应用程序泄漏进行了几天令人沮丧的研究后,我发现不止一个。我设法解决了这些问题,我最初发布的那个与 John Vint 的帖子有关,缓冲控件存在问题,导致 TextView 中的 SpannableStringBuilder 对象大量积累,所以我接受了他的帖子。现在我对另一个奇怪的泄漏有不同的问题,但它与原始帖子无关,所以我要提出一个新问题。
【问题讨论】:
-
你在哪里调用 Write2Tab?
-
据我所知,Java 中的内存泄漏是不可能的。您占用的所有内存都在您的控制之下,否则垃圾收集器会释放它。
-
@HAL9000 如果你一直分配内存,你的应用会因为垃圾收集器的工作而变慢。
-
我建议您阅读维基百科上的垃圾收集和弱引用 - en.wikipedia.org/wiki/Weak_reference
-
@RobinDijkhof 这个方法是从调用 Write2Tab 的同一个 Activity 中调用的。 AsyncTask 从套接字获取线路,通过 Handler 将其发送到 MainActivity,然后调用 Write2Tab。
标签: java android multithreading memory-leaks