我在Activity上下文中有一个TabHost,其中TextView与每个选项卡相关联。目前还有一个管理TCP套接字的AsyncTask,当它收到某种信息时,它会被发送到主Activity处理程序,后者调用一个方法将文本附加到当前的TextView。
好吧,经过一段时间(约5分钟)的跑步,我注意到它是如何开始悬挂的,最后我得到一个ANR。所以我安装了Memory Analyzer for Eclipse,并与DDMS一起,我找到了什么似乎是瓶颈,但没有找到如何处理它。
使用前面提到的工具,我能够看到数百行像这张图片中的那些:
BTW :该图中有一个奇怪的细节,线程ID始终为1;每个线程不应该不同,因为在不同的线程上调用append?
这些数百行引用了您在上面的代码中看到的两个“附加”。我是线程世界的新手,所以如果你看到一些奇怪的东西,我会感激任何建议。这是瓶颈所在的代码:
// 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对象进行了积累,所以我接受了他的帖子。现在我有另一个奇怪的泄漏问题,但它与原始帖子无关,所以我打算开一个新问题。
答案 0 :(得分:0)
StringBuilder变得多大?
如果线程卡在253处,就像它在堆中所显示的那样,我可以想到的是,你的堆空间已经用完了,并且达到了GC开销限制。
如果是这种情况,你需要缓冲StringBuilder(即如果长度> N,则移除最旧的行,其中N是足够大的数字以具有历史但小到足以防止OOM)。