java outOfMemoryError 与 stringbuilder
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2431040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java outOfMemoryError with stringbuilder
提问by user276712
I'm getting a java outOfMemoryError when I call this method - i'm using it in a loop to parse many large files in sequence. my guess is that result.toString()
is not getting garbage collected properly during the loop. if so, how should i fix it?
当我调用这个方法时,我得到一个 java outOfMemoryError - 我在循环中使用它来依次解析许多大文件。我的猜测是result.toString()
在循环期间没有正确收集垃圾。如果是这样,我应该如何解决它?
private String matchHelper(String buffer, String regex, String method){
Pattern abbrev_p = Pattern.compile(regex);//norms U.S.A., B.S., PH.D, PH.D.
Matcher abbrev_matcher = abbrev_p.matcher(buffer);
StringBuffer result = new StringBuffer();
while (abbrev_matcher.find()){
abbrev_matcher.appendReplacement(result, abbrevHelper(abbrev_matcher));
}
abbrev_matcher.appendTail(result);
String tempResult = result.toString(); //ERROR OCCURS HERE
return tempResult;
}
采纳答案by erickson
Written this way, you'll need roughly 6bytes of memory for every character in the file.
以这种方式编写,文件中的每个字符大约需要6个字节的内存。
Each character is two bytes. You have the raw input, the substituted output (in the buffer), and you are asking for a third copy when you run out of memory.
每个字符是两个字节。您有原始输入、替换输出(在缓冲区中),并且在内存不足时要求第三份副本。
If the file is encoded in something like ASCII or ISO-8859-1 (a single-byte character encoding), that means it will be six times larger in memory than on disk.
如果文件以 ASCII 或 ISO-8859-1(单字节字符编码)之类的方式编码,则意味着它在内存中将比在磁盘上大六倍。
You could allocate more memory to the process, but a better solution might be to process the input "streamwise"—read, scan, and write the data without loading it all into memory at once.
您可以为进程分配更多内存,但更好的解决方案可能是“流式”处理输入——读取、扫描和写入数据,而无需一次性将其全部加载到内存中。
回答by fastcodejava
You could try returning a StringBuffer
and setting it to null
after use.
您可以尝试返回 aStringBuffer
并将其设置为null
使用后。
回答by bryantsai
If your files to be processed are all very large, say more than a few hundred MB, then you really should go with stream processing instead of this "loading all into memory" way, just as @erickson suggested.
如果您要处理的文件都非常大,比如说超过几百 MB,那么您真的应该使用流处理而不是这种“将所有文件加载到内存中”的方式,正如@erickson 建议的那样。
Otherwise, there are a few things you could try, all to reduce memory usage as much as possible:
否则,您可以尝试一些方法,以尽可能减少内存使用:
- Try properly enlarge your heap size if not yet (when applicable).
- Give
StringBuffer
an initial size same as the lenght of the givenString
buffer
. This should reduce the unnecessary memory usage while expanding theStringBuffer
in the process. I assume it is only replacing certain words of the original string and should be more or less the same in length. - If possible, maybe you could return the generated
StringBuffer
object instead. Calling itstoString()
only after you get rid of the originalString
object.
- 如果还没有(如果适用),请尝试适当扩大您的堆大小。
- 给出
StringBuffer
与给定的长度相同的初始大小String
buffer
。这应该减少不必要的内存使用,同时扩展StringBuffer
进程。我认为它只是替换原始字符串的某些单词,并且长度应该或多或少相同。 - 如果可能,也许您可以返回生成的
StringBuffer
对象。toString()
只有在摆脱原始String
对象后才调用它。
回答by nicerobot
I agree with the other responses ... but ... simply because the exception occurs there doesn't necessarilymean it's the problem. You may very well be leaking memoryelsewhere and that just happens to be the place that it's revealed. You should run a profilerto examine memory usage and verify exactly what objects aren't being collected.
我同意其他回答......但是......仅仅因为异常发生并不一定意味着这是问题所在。您很可能在其他地方泄漏了内存,而这恰好是它显示出来的地方。您应该运行分析器来检查内存使用情况并准确验证哪些对象没有被收集。
回答by Mohammed
I reckon the problem with StringBuilder.append()
. When Matcher appends sequence of characters to the Builder.
我认为问题在于StringBuilder.append()
. 当 Matcher 将字符序列附加到 Builder 时。
As explained in article about OutOfMemoryError with StringBuilder/StringBuffer, it is a known issue that append() will double the capacity if internal buffer chars
if the capacity is not sufficient.
Go for streams as suggested by Erickson.
正如关于带有 StringBuilder/StringBuffer 的 OutOfMemoryError文章中所解释的,chars
如果容量不足,则 append() 会将容量加倍,如果内部缓冲区容量不足,这是一个已知问题。按照埃里克森的建议去寻找流。
回答by user464034
Yes! Don't buffer in memory otherwise you'll run out of it specially if you're going over 2MB on I/O.
是的!不要在内存中缓冲,否则如果您的 I/O 超过 2MB,您将特别用完它。
Recommended link for fixing and appending text: http://java.ittoolbox.com/documents/appending-data-to-a-file-18786
修复和附加文本的推荐链接:http: //java.ittoolbox.com/documents/appending-data-to-a-file-18786