代码之家  ›  专栏  ›  技术社区  ›  Alex Volovoy

SAX、StringBuilder和内存泄漏

  •  4
  • Alex Volovoy  · 技术社区  · 15 年前

    我有个奇怪的问题。我正在分析具有大文本字段的文档。 在“我的角色”部分,我使用的是StringBuilder

    currentStory.append(ch, start, length);
    

    然后在结束语中,我将它分配给对象上的适当字段。

      if (name.equals(tagDesc)) {
         inDesc = false;
         if (currentItem != null ) {
             currentItem.setSummaryText(currentStory.toString());
         }
         currentStory.setLength(0);
      }
    

    setSummaryText(String text) 方法是:

        public void setSummaryText(String text) {
          Story = text;
        }
    

    我的记忆也快用完了。

    如果我把setSummaryText改成这样的奇怪的东西

    public void setSummaryText(String text) {
          char[] local = text.toString()
          Story = new String(local);
       }
    

    我很好。我就是不知道我把那个证明放在哪里?Story是用“”初始化的此对象的成员变量; 注意-分配给本地字符串变量而不是char[]-也会失败。

    1 回复  |  直到 12 年前
        1
  •  5
  •   David Webb    15 年前

    我认为这可能与 StringBuffer toString() 方法。

    太阳神JavaDoc说:

    可以对该方法进行编码,以便在不分配新内存来保存字符序列副本的情况下创建新的字符串对象。相反,字符串可以共享字符串缓冲区使用的内存。任何改变字符串缓冲区内容或容量的后续操作都必须在那时复制内部缓冲区。当使用字符串缓冲区实现字符串连接操作时,此策略可以有效地减少由该操作分配的内存量。

    因为你用的是 伸缩缓冲器 setLength(0) 它可能保留了对它所创建的所有字符串的引用 托斯特林() .

    替换:

    currentStory.setLength(0);
    

    用:

    currentStory = new StringBuffer();
    

    看看能不能解决问题。我不认为这会有更多的开销,因为在这两种情况下,您都需要创建一个新的 char[] 数组,因为在第一种情况下, String 创建与 托斯特林() .

    另外,您应该考虑使用 StringBuilder 因为他们更喜欢 伸缩缓冲器 .