dim*_*mas 1 java memory string stringbuilder
我有这段代码将StringBuilders的ArrayList转换为字符串的ArrayList:
码:
public ArrayList<String> convGenSeqToString(ArrayList<StringBuilder> buff){
ArrayList<String> convBuf = new ArrayList<String>();
for (StringBuilder xVar: buff){
convBuf.add(xVar.toString());
}
return convBuf;
}
Run Code Online (Sandbox Code Playgroud)
我的代码适用于15-20MB文本文件的文件.但是我有一个44MB的文本文件,每当我用该文本文件运行我的程序时,我总是会收到此错误.
错误:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2746)
at java.util.ArrayList.ensureCapacity(ArrayList.java:187)
at java.util.ArrayList.add(ArrayList.java:378)
at Recognition.convGenSeqToString(Recognition.java:157)
at Recognition.genSeq(Recognition.java:145)
at Recognition.Recognitions(Recognition.java:96)
at ChainDetection.main(Detection.java:25)
Run Code Online (Sandbox Code Playgroud)
我已经使用-Xmx2048M增加了JVM运行配置中的内存,但仍然存在相同的错误.我将错误指向上面显示的代码并突出显示以下行:
convBuf.add(xVar.toString());
Run Code Online (Sandbox Code Playgroud)
有没有其他方法可以将StringBuilder转换为字符串而不使用该.toString()方法?我在其他论坛中看到过,他们也为toString创建了自定义类,但我还不熟悉泛型和一些"@"关键字.任何人都有如何解决这个问题的建议或指导?
我根据vanza的建议编辑了我的代码,它是:
public ArrayList<String> convGenSeqToString(ArrayList<StringBuilder> buff){
ArrayList<String> convBuf = new ArrayList<String>(buff.size());
Iterator <StringBuilder> iterBuf = buff.iterator();
while (iterBuf.hasNext()){
StringBuilder x = iterBuf.next();
convBuf.add(x.toString());
iterBuf.remove();
}
return convBuf;
}
Run Code Online (Sandbox Code Playgroud)
错误信息:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.ArrayList.<init>(ArrayList.java:132)
at Recognition.convGenSeqToString(Recognition.java:154)
at Recognition.genSeq(Recognition.java:145)
at Recognition.Recognitions(Recognition.java:96)
at ChainDetection.main(ChainDetection.java:25)
Run Code Online (Sandbox Code Playgroud)
我尝试使用buff.size()和没有buff.size(),我得到了相同的错误消息.但似乎我的错误消息现在减少到5.还有其他想法吗?提前致谢!
如果不了解您的计划,我将不会对您采取的方法发表任何评论,只会对您发布的代码发表评论.听起来很奇怪,一个44MB的文件填满了2G堆.
您可以做的一件事是预先在目标数组中分配空间:
ArrayList<String> convBuf = new ArrayList<String>(buf.size());
Run Code Online (Sandbox Code Playgroud)
这将避免ArrayList调整大小步骤,该步骤创建现有列表的副本(并显示在堆栈跟踪中).
您可以尝试的另一件事是在构建String数组时释放对原始StringBuilders的引用.使用Iterator(而不是"for each"循环),并在每次迭代时buff使用数组中的StringBuilder Iterator.remove(); 这样你就可以释放一些内存,让垃圾收集器在内存不足的情况下回收.
但同样,使用如此小的文件耗尽内存听起来很奇怪.也许用jvisualvm查看你的堆可以解决一些问题.
| 归档时间: |
|
| 查看次数: |
2212 次 |
| 最近记录: |