StringBuilder de l'erreur de mémoire lorsque l'on travaille avec de grandes chaînes de caractères en java
Je suis passé de String test += str;
où test
a grandi de façon exponentielle grand avec des milliers et des milliers de caractères. Il a fallu 45 minutes pour s'exécuter, probablement à partir de la création de grandes chaînes et de suppression des ordures. J'ai ensuite décalés l'entrée comme ce qui l'amena à 30 secondes.
Cela semble être le bon moyen de le faire, mais il a bien fonctionné:
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 = "";
}
J'ai alors découvert que StringBuilder
existe, et j'ai essayé de l'utiliser car, en remplaçant toutes les opérations de la chaîne avec elle.
Le problème est, je reçois un java.lang.OutOfMemoryError
avec une mémoire java heap overflow. Je pense que la chaîne est trop longue pour stocker dans la mémoire comme un StringBuilder
l'objet, car il fait environ 1/50ème de la progression que mon code précédent ne avant de s'écraser avec une erreur de mémoire insuffisante. C'est seulement en travaillant avec peut-être sous un millier de caractères.
Pourquoi une chaîne de conserver la totalité de la production et cela ne peut pas être proches? Aussi, si j'ai à ajouter du texte à JTextPane
, la quantité de mémoire qui en ont besoin? Si je dump la StringBuilder
contenu de JTextpane
et de garder à l'ajout et à la compensation StringBuilder
qui ne semble pas fonctionner non plus.
Voici le code existant. La Page est juste un objet est transmis:
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);
}
}
Voici l'erreur:
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)
Je pense que c'est une trace de la pile est:
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)
- Quels sont tes paramètres de la VM? Essayez d'augmenter la taille du tas.
- Pourriez-vous s'il vous plaît ajouter le code lorsque vous utilisez la classe StringBuilder. L'erreur est plus susceptible d'être là.
- Plus de détails en aide. Je doute que la chaîne de caractères en mémoire est de vous faire manquer de mémoire. Avez-vous de la stacktrace?
- J'ai appelé Thread.dumpStack();. Je suis un noob aussi loin que le codage avancé, je suppose que c'est la trace de la pile qui s'imprime lors de l'appel de cette.
Vous devez vous connecter pour publier un commentaire.
Apparemment, votre application ne débite pas assez de mémoire pour terminer l'opération. Si vous avez besoin de spécifier la mémoire des drapeaux à votre machine virtuelle. Vous pouvez essayer ce qui suit:
Où:
Bien l'une des choses qui pourrait arriver, c'est le fait que, dans Java, java.lang.La chaîne obtient le traitement spécial. Les chaînes sont immuables, et donc la JVM place chaque objet de type String dans une piscine .Le rôle de cette piscine, entre autres, c'est le fait qui est utilisé comme une sorte de "cache" où si vous créez plusieurs instances de chaînes avoir le vrai "texte" valeur identique, la même instance sera réutilisée de la piscine. De cette façon, la création de ce qui semble être un grand nombre de Chaîne des instances de l'objet avec le même texte à l'intérieur va en effet revenir à avoir très peu de véritables instances de Chaîne dans la mémoire. D'autre part, si vous utilisez le même texte pour initialiser plusieurs StringBuilder cas, ceux qui seront en fait des instances distinctes (contenant le même texte), et occupant ainsi plus de mémoire.
D'autre part, la concaténation de Chaînes de caractères (comme
String c = "a"+"b";
) va en fait créer plusieurs instances d'objet que si vous le faites avec StribgBuilder (commenew StringBuilder("a").append("b");
).