0

我正在尝试将文件文本附加到我的 JTextPane 中。这对于小于 10Mb 但大于其大小的文件(我检查了 ~50Mb)非常有用,我得到了臭名昭著的异常“OutOfMemoryError:Java 堆空间”。

我试图理解如果两种方法都是静态的并且在while(line!= null)下的每次迭代中都没有“新”,为什么我会获得java堆内存。如果我可以在常规 txt 编辑器中打开文件,为什么这段代码无法执行?

代码如下所示:

public static void appendFileData(JTextPane tPane, File file) throws Exception
{
    try{

        //read file's data
        BufferedReader br = new BufferedReader(new FileReader(file));
        String line = br.readLine();

        try{ 
               while (line != null) 
               { 
                   JTextPaneUtil.appendToConsole(tPane, "\n"+line,Color.WHITE, "Verdana", 14);
                   line = br.readLine();
               } 

           }finally 
           {
               br.close();
           }

    }catch(Exception exp)
    {
        throw exp;
    }
}

appendToConsole 是:

public static void appendToConsole(JTextPane console, String userText, Color color, String fontName, int fontSize)
{
  StyleContext sc = StyleContext.getDefaultStyleContext();
  AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, color);
  aset = sc.addAttribute(aset, StyleConstants.FontFamily, fontName);
  aset = sc.addAttribute(aset, StyleConstants.FontSize, fontSize);
  aset = sc.addAttribute(aset,StyleConstants.Alignment, StyleConstants.ALIGN_CENTER);

  int len = console.getDocument().getLength();
  console.setCaretPosition(len);
  console.setCharacterAttributes(aset, false);
  console.replaceSelection(userText);
}
4

2 回答 2

3

为什么要为每一行添加属性?Swing 需要做很多工作来跟踪所有这些属性,或者将它们合并为整个文件的一个属性。

在将所有数据加载到文本窗格后,尝试使用如下代码一次性设置整个文本窗格的属性。

SimpleAttributeSet center = new SimpleAttributeSet();
StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
doc.setParagraphAttributes(0, doc.getLength(), center, false);

另外,我认为您不需要使用属性来设置字体。你应该能够使用:

textPane.setFont(...);
于 2013-06-11T20:01:17.657 回答
2

即使您的代码没有显式调用“新”关键字,也不意味着您调用的代码不是。我假设每次调用时一遍又一遍地设置字符属性appendToConsole会创建一些底层对象 - 不过,您必须查看源代码或在分析器中运行它才能确定。

此外,可以在没有“new”的情况下创建字符串,因此br.readLine()为源文件中的每一行创建并返回一个新字符串,并在其上附加一个“\n”也会创建另一个新字符串。所有这些字符串都被添加到您的 JTextPane 的文档模型中,最终将保存您正在加载的文件的全部内容。

默认的 JVM 堆大小约为 64MB - 在 JVM 和代码中加载约 50MB 的文件以及其他支持类显然会使您超出该限制,然后您会收到 OutOfMemoryError。

要查看程序中真正分配了哪些内容以及存在哪些引用,请通过VisualVM之类的分析器运行您的程序。

于 2013-06-11T19:42:09.137 回答