【发布时间】:2016-04-19 09:59:25
【问题描述】:
在我的程序中,我想读取一个 PLSQL 文件
并删除以 --
开头的 cmets
我将每条评论都放在它自己的行中,这样我就可以删除该特定行(有时我将代码和 cmets 放在同一行中,这就是我正在做的“\n--”)。
我将我的程序导出到一个 jar 文件,它在我的桌面上运行良好,但在另一台计算机上(读取不同的 PLSQL 文件)即使我尝试它也会给我 Java 堆空间错误
java -Xmx256m -jar myjar.jar
错误:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
at java.lang.AbstractStringBuilder.append(Unknown Source)
at java.lang.StringBuffer.append(Unknown Source)
at ParserDB.ScriptNoComment(ParserDB.java:142)
at ParserDB.GetTheName(ParserDB.java:54)
at Rapport.SearchCcInDB(Rapport.java:189)
at Rapport.listDB(Rapport.java:77)
at Rapport.main(Rapport.java:472)
... 5 more
我的代码是:
public static String ScriptNoComment(String fileName){
String result = null ;
try{
FileInputStream fstream = new FileInputStream(fileName);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
StringBuffer strOut = new StringBuffer();
StringBuilder Out = new StringBuilder();
String strLine;
while ((strLine = br.readLine()) != null) {
if(strLine.contains("--")){
strLine = strLine.replaceAll("--","\n--");
}
strOut.append(strLine+"\n");
}
in.close();
//delete comment
String[] lines = strOut.toString().split("\\n");
for(String s: lines){
if(s.contains("--")){
s="";
}
Out.append(s+"\n");
}
result = Out.toString();
result = result.toUpperCase();
result = result.replaceAll("\"", "");
result = result.replaceAll("\\r\\n|\\r|\\n", " ");
result = result.replaceAll("\\s+", " ");
}catch (Exception e){
System.err.println("Error: " + e.getMessage());
}
return result ;
}
有没有办法优化我的代码,提前谢谢
编辑
1-)
我使用以下命令检查了另一台计算机中的堆大小:
java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"
结果是:min:16M,Maxsize:256M 所以我应该在 java -jar :-Xmx512m 而不是 -Xms256m 中录音
2-) 我删除了(只是为了测试)stringbuilder和所有replaceAll,但仍然得到同样的错误,因为我的文件太大了。
所以我所做的是计算我正在阅读的每个文件的行数并尝试(取决于行)例如仅读取前 50 行并将我的方法仅应用于这 50 行
谢谢大家的回答
【问题讨论】:
-
也许只是给它更多的堆空间? -Xmx2g 例如
-
更好地使用 Stream 方法。如果你的文本很大,它会消耗大量内存,因为每个操作都会分配一个
new String()。如果你在读取文件时遇到了麻烦,那么你在正则表达式的操作上就会遇到更大的麻烦。 -
这个程序太复杂了。最后,您有一个包含输入的 StringBuffer、一个具有相同内容的字符串数组和一个 StringBuilder,它还包含除 cmets 之外的所有内容。这是内存要求的三倍。相反,您可以逐行读取文件,检查该行是否包含注释(或内容),如果是则省略/缩短它。您也可以在线进行替换,因此结果中不需要它们。这样做,您的内存需求将大大减少。
-
@UweAllner 使用 -Xmx2g 是否有任何损坏,我的意思是这个 java -Xmx2g -jar myjar.jar 可以阻止我的计算机吗?
-
@ammoQ 是的,但有时我将代码和 cmets 放在同一行,这就是我正在做的方式“\n--”
标签: java regex stringbuilder heap-memory