在java中使用大字符串时StringBuilder内存不足错误 [英] StringBuilder out of memory error when working with large strings in java
问题描述
我从字符串测试+ = str;
其中 test
成千上万的字符成倍增长。运行需要45分钟,可能是因为创建了大字符串并删除了垃圾。然后,我将这样的输入交错,这使它达到30秒。
I went from String test += str;
where test
grew exponentially large with thousands and thousands of characters. It took 45 minutes to run, probably from creating large strings and deleting garbage. I then staggered the input like this which brought it to 30 seconds.
这似乎是一种便宜的方式,但效果很好:
This seems like the cheap way to do it, but it worked well:
if (secondDump.length() > 50)
{
intermedDump = intermedDump + secondDump;
secondDump = "";
}
if (intermedDump.length() > 100)
{
thirdDump = thirdDump + intermedDump;
intermedDump = "";
}
if (thirdDump.length() > 500)
{
fourthDump = fourthDump + thirdDump;
thirdDump = "";
}
if (fourthDump.length() > 1000)
{
fifthDump = fifthDump + fourthDump;
fourthDump = "";
}
//with just this and not sixth. Runtime>>>> : 77343
if (fifthDump.length() > 5000)
{
sixthDump = sixthDump + fifthDump;
fifthDump = "";
}
//with just this. Runtime>>>> : 35903Runtime>>>> : 33780
if (sixthDump.length() > 10000)
{
fillerDump = fillerDump + sixthDump;
sixthDump = "";
}
然后我发现 StringBuilder
存在,我一直在尝试使用它,因为用它替换所有的字符串操作。
I then discovered that StringBuilder
exists, and I've been trying to use it since, replacing all string operations with it.
问题是,我不断收到带有java内存堆溢出的 java.lang.OutOfMemoryError
。我认为字符串太长了,无法作为 StringBuilder
对象存储在内存中,因为它占用了我以前的代码在崩溃之前所做的大约1/50的进度内存错误。它只能使用不到一千个字符。
The problem is, I keep getting an java.lang.OutOfMemoryError
with a java memory heap overflow. I think the string is just too long to store in memory as a StringBuilder
object, because it makes about 1/50th of the progress that my previous code did before crashing with an out of memory error. It's only working with maybe under a thousand characters.
为什么一个字符串可以保存整个输出,这不能接近?另外,如果我将文本追加到 JTextPane
,那需要多少内存?如果我将 StringBuilder
内容转储到 JTextpane
并继续追加并清除 StringBuilder
这似乎也不起作用。
Why can a string hold the entire output and this can't come close? Also, if I append text to JTextPane
, how much memory does that need? If I dump the StringBuilder
contents to JTextpane
and keep appending and clearing StringBuilder
that doesn't seem to work either.
这是现有代码。 Page只是一个被传递的对象:
Here is the existing code. Page is just an object being passed:
protected void concatPlates(page PageA) throws IOException
{
if (backend.isFirstPage == false)
{
frontend.fillOutputPane("\n " +
" \n", PageA);
frontend.fillOutputPane(" " +
" \n", PageA);
frontend.fillOutputPane(" " +
" \n", PageA);
}
for (int i = 0; i < PLATELEN-1; i++)
{
if (arrLeftCol[i].length() == 0)
{
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
frontend.fillOutputPane(arrLeftCol[i].append(
arrRightCol[i]));
}
else
{
PageA.tempStrBuff = new StringBuilder(arrLeftCol[i].substring(0,40));
frontend.fillOutputPane(PageA.tempStrBuff.append(arrRightCol[i]));
}
arrLeftCol[i].append("");
arrRightCol[i].append("");
backend.isFirstPage = false;
}
}
//this is the frontend class
public static void fillOutputPane(String s, page PageA)
{
fillOutputPane(PageA.getStrBuf());
}
public static void fillOutputPane(StringBuilder stringBuild)
{
try
{
str.append(stringBuild);
}
catch (java.lang.OutOfMemoryError e)
{
System.out.println((str.length() * 16) /8);
//System.out.println(str);
System.out.println("out of memory error");
System.exit(0);
}
}
这是错误:
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
at java.lang.AbstractStringBuilder.append(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at backend.fill(backend.java:603)
at frontend$openL.actionPerformed(frontend.java:191)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
我认为这就是堆栈跟踪:
I think this is what a stack trace is:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Unknown Source)
at frontend.fillOutputPane(frontend.java:385)
at page.concatPlates(page.java:105)
at backend.setPlate(backend.java:77)
at backend.fill(backend.java:257)
at frontend$openL.actionPerformed(frontend.java:191)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)81240560
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
推荐答案
显然你的应用程序没有足够的内存来完成操作。因此,您需要为虚拟机指定内存标志。您可以尝试以下方法:
Apparently your application doen't have enough memory for complete the operation. So you need to specify memory flags to your virtual machine. You can try the following:
java -Xms256m -Xmx512m YourApp
其中:
- 程序在启动时分配的最小内存(在示例256 MB)
- 如果需要更多(在示例中为512 MB),程序分配的Xmx最大内存
这篇关于在java中使用大字符串时StringBuilder内存不足错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!