2011-12-02 16 views
6

में बड़े तारों के साथ काम करते समय स्ट्रिंगबिल्डर स्मृति त्रुटि से बाहर मैं String test += str; से चला गया जहां test हजारों और हजारों पात्रों के साथ तेजी से बड़ा हुआ। बड़े स्ट्रिंग बनाने और कचरे को हटाने से शायद 45 मिनट लग गए। तब मैंने इस तरह के इनपुट को झुका दिया जो इसे 30 सेकंड तक लाया।जावा

यह यह करने के लिए सस्ता तरीका की तरह लगता है, लेकिन यह अच्छी तरह से काम:

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 मौजूद है, और मैं इसके साथ सभी स्ट्रिंग आपरेशन की जगह के बाद से इसका इस्तेमाल करने की कोशिश कर रहा है, ।

समस्या है, मैं एक जावा स्मृति ढेर अतिप्रवाह के साथ एक java.lang.OutOfMemoryError मिलती रहती है। मुझे लगता है कि स्ट्रिंग StringBuilder ऑब्जेक्ट के रूप में स्मृति में स्टोर करने के लिए बहुत लंबा है, क्योंकि यह प्रगति का लगभग 1/50 वां है जो मेरे पिछले कोड को स्मृति त्रुटि से बाहर होने से पहले क्रैश करने से पहले किया था। यह केवल हजारों पात्रों के साथ काम कर रहा है।

क्यों एक स्ट्रिंग पूरे उत्पादन कर सकते हैं और इस पास नहीं आ सकता? साथ ही, अगर मैं JTextPane पर टेक्स्ट जोड़ता हूं, तो इसकी कितनी मेमोरी की आवश्यकता है? अगर मैं JTextpane को StringBuilder सामग्री डंप और जोड़कर और StringBuilder है कि या तो काम करने के लिए प्रतीत नहीं होता समाशोधन रहते हैं।

यहाँ मौजूदा कोड है। पृष्ठ सिर्फ एक वस्तु पारित किया जा रहा है:

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) 

मुझे लगता है कि यह है कि क्या एक स्टैक ट्रेस है:

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) 
+1

आपके वीएम पैरामीटर क्या हैं? ढेर आकार बढ़ाने की कोशिश करें। – Viruzzo

+0

क्या आप कोड जोड़ सकते हैं जहां आप स्ट्रिंगबिल्डर वर्ग का उपयोग कर रहे हैं। त्रुटि वहां होने की संभावना अधिक है। – JustinKSU

+0

अधिक जानकारी मदद मिलेगी। मुझे संदेह है कि स्मृति में स्ट्रिंग आपको स्मृति से बाहर कर रही है। क्या आपके पास स्टैकट्रैक है? –

उत्तर

5

जाहिर है आपके आवेदन doen't ऑपरेशन को पूरा करने के लिए पर्याप्त स्मृति है। तो आपको अपनी वर्चुअल मशीन पर मेमोरी फ्लैग निर्दिष्ट करने की आवश्यकता है।

java -Xms256m -Xmx512m YourApp 

कहाँ:

  • XMS minimun स्टार्टअप पर अपने कार्यक्रम द्वारा आबंटित स्मृति (उदाहरण के 256 एमबी में)
  • Xmx maximun स्मृति अपने कार्यक्रम द्वारा आवंटित करता है, तो इसकी जरूरत आप निम्न कोशिश कर सकते हैं अधिक (उदाहरण में 512 एमबी)
+1

यह एक त्वरित फिक्स समाधान है जो वास्तव में स्केल बनाम स्ट्रिंगबिल्डर का उपयोग करने के तरीके को स्केल या व्याख्या नहीं करता है, वास्तव में स्मृति खपत को प्रभावित करता है। –

+2

इसे त्वरित फिक्स नहीं माना जाता है - जितना अधिक डेटा आप स्मृति में रखना चाहते हैं उतनी अधिक मेमोरी आपको चाहिए। – Puce

+0

अल्थौग स्ट्रिंगबिल्डर को एक स्ट्रिंग ऑब्जेक्ट की तुलना में थोड़ी अधिक मेमोरी की आवश्यकता हो सकती है क्योंकि यह नए डेटा के लिए कुछ मुफ्त स्लॉट खोलता है। – Puce

3

अच्छी तरह से हो सकता है कि चीजों में से एक यह तथ्य है कि जावा, java.lang.String में विशेष उपचार मिलता है। स्ट्रिंग्स अपरिवर्तनीय हैं, और इस प्रकार JVM पूल में प्रत्येक स्ट्रिंग ऑब्जेक्ट को रखता है। इस पूल की भूमिका, दूसरों के बीच एक तथ्य है जिसे "कैश" के रूप में उपयोग किया जाता है, जहां आप वास्तविक "टेक्स्ट" वाले कई स्ट्रिंग उदाहरण बनाते हैं। समान मूल्य, उसी उदाहरण को पूल से पुन: उपयोग किया जाएगा। इस तरह से एक ही पाठ के साथ स्ट्रिंग ऑब्जेक्ट इंस्टेंस की बड़ी संख्या में प्रतीत होता है जो इस तरह बना रहा है, वास्तव में स्मृति में बहुत कम वास्तविक स्ट्रिंग उदाहरणों को वापस करने के लिए वापस आ जाएगा। दूसरी ओर, यदि आप एकाधिक स्ट्रिंगबिल्डर उदाहरणों को प्रारंभ करने के लिए एक ही पाठ का उपयोग करते हैं, तो वे वास्तव में अलग-अलग उदाहरण होंगे (एक ही पाठ वाले), और इस प्रकार अधिक स्मृति पर कब्जा कर लेंगे।

दूसरी ओर, स्ट्रिंग्स (जैसे String c = "a"+"b";) को संयोजित करना वास्तव में अधिक ऑब्जेक्ट उदाहरण बनाएगा कि यदि आप इसे स्ट्रिबबिल्डर (जैसे new StringBuilder("a").append("b");) के साथ करते हैं।

+0

मैं देखता हूं। तो क्या आपको लगता है कि यह स्मृति त्रुटि से बाहर हो सकता है? मैंने नहीं सोचा था कि एक सिंगल स्ट्रिंगबिल्डर ऑब्जेक्ट एक हजार वर्णों के साथ उस स्मृति का उपयोग करेगा। – montag

+0

मुझे अभी एहसास हुआ कि यह शायद हजारों वर्णों से अधिक है। – montag

+0

क्या आप इसे ग्रहण के साथ डीबग कर सकते हैं यह पता लगाने के लिए कि स्ट्रिंग कितनी देर तक है? – davidfrancis