将大文本附加到'OutOfMemoryError:Java堆空间的jtextpane结果中

时间:2013-06-11 19:13:54

标签: java swing jtextpane heap-memory

我正在尝试将文件的文本附加到我的JTextPane中。这适用于10Mb以下但大小超过它的文件(我检查了~50Mb)我得到了臭名昭着的异常'OutOfMemoryError:Java堆空间'。

我试图理解为什么如果两个方法都是静态的并且在while(line!= null)下的每次迭代中都没有'new',我会得到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);
}

2 个答案:

答案 0 :(得分:3)

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

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

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

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

textPane.setFont(...);

答案 1 :(得分:2)

即使您的代码未明确调用'new'关键字,也不意味着您调用的代码不是。我假设每次调用appendToConsole时反复设置字符属性都会创建一些底层对象 - 你必须看到源代码或者在分析器中运行它才能确定。

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

默认的JVM堆大小约为64MB - 在JVM中加载一个~50MB的文件以及其他支持类,在你的代码中显然会超过这个限制,然后你得到一个OutOfMemoryError。

要了解您的计划中实际分配了什么,以及有哪些参考资料,请通过VisualVM等分析器运行您的程序。