Java 内存泄漏线程

Java 内存泄漏线程,java,android,multithreading,memory-leaks,Java,Android,Multithreading,Memory Leaks,在活动上下文中,我有一个TabHost,其中包含与每个选项卡关联的文本视图。目前还有一个AsyncTask管理TCP套接字,当它接收到某种信息时,它将被发送到主活动处理程序,主活动处理程序调用一个方法将文本附加到当前TextView 嗯,跑步一段时间(大约5分钟)后,我注意到它开始挂起,最后我得到了一个ANR。因此,我安装了Eclipse内存分析器,并与DDMS结合使用,我能够找出什么似乎是瓶颈,但无法找到如何处理它 使用前面提到的工具,我可以看到数百行,如图中所示: 顺便说一句:那张图片中有

在活动上下文中,我有一个TabHost,其中包含与每个选项卡关联的文本视图。目前还有一个AsyncTask管理TCP套接字,当它接收到某种信息时,它将被发送到主活动处理程序,主活动处理程序调用一个方法将文本附加到当前TextView

嗯,跑步一段时间(大约5分钟)后,我注意到它开始挂起,最后我得到了一个ANR。因此,我安装了Eclipse内存分析器,并与DDMS结合使用,我能够找出什么似乎是瓶颈,但无法找到如何处理它

使用前面提到的工具,我可以看到数百行,如图中所示:

顺便说一句:那张图片中有一个奇怪的细节,线程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();

  [...]
}
我的代码中还有两个内存泄漏我可以修复,但这一个开始有点难。。。你知道为什么会发生这种情况以及如何解决吗

--------------编辑-------------------


在对我的应用程序中的漏洞进行了几天令人沮丧的研究之后,我发现不止一个漏洞。我设法解决了这些问题,我最初发布的帖子与John Vint的帖子有关,缓冲控制出现了问题,导致文本视图中SpannableStringBuilder对象大量累积,因此我接受了他的帖子。现在我有一个与另一个奇怪的漏洞不同的问题,但它与原始帖子无关,因此我将打开一个新问题。

StringBuilder有多大

如果线程停留在253,就像它在堆dumb中显示的那样,那么我所能想到的就是堆空间已经用完,并且已经达到了GC开销限制


如果是这种情况,您需要对StringBuilder进行缓冲(即如果长度大于N,则删除最早的行,其中N是一个足够大的数字,可以有历史记录,但足够小,可以防止OOM)。

您在哪里调用Write2Tab?据我所知,Java中不可能出现内存泄漏。您占用的所有内存都在您的控制之下,否则,垃圾收集器将释放它。@HAL9000如果您继续分配内存,由于垃圾收集器的工作,您的应用程序将很慢。我建议您在wikipedia-@RobinDijkhof上阅读有关垃圾收集和weakreferences的内容。此方法是从调用Write2Tab的同一活动中调用的。AsyncTask从套接字获取行,通过处理程序将其发送到MainActivity,在那里调用Write2Tab。实际上,我正在这样做,每个选项卡都有30行的限制。如果超过此限制,最旧的当前_行-30将被擦除。这是另一个漏洞,但我能够修复它。@user3001496 Ok。不幸的是,没有足够的信息。在需要的时候,似乎所有的东西都应该排成一行进行分配。注意ThreadId:1可能只是指UI线程。当您说
runOnUiThread
时,它将任务置于队列中,稍后将运行它。