我正在尝试将文件的文本附加到我的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);
}
答案 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等分析器运行您的程序。